Статьи

Включение JavaScript в плагины или темы — правильный путь

На момент написания статьи на WordPress.org было доступно более 33 000 плагинов и 2600 тем, и мы, вероятно, можем добавить больше, которых нет на этой платформе. Они могут делать много разных вещей, и часто они используют JavaScript для предоставления некоторых функций.

JavaScript и WordPress

В принципе, включение кода JavaScript в тему или плагин не сложно: то, что производит WordPress, — это не что иное, как HTML, поэтому использование тега script с кодом непосредственно в нем или в файле, связанном с атрибутом src может быть достаточно — если вы один, развивающийся в изоляции.

Дело в том, что вы не одиноки . Люди, использующие WordPress, могут устанавливать плагины или темы рядом с вашими, и разработчики этих инструментов также могут использовать JavaScript. Более того, сам WordPress использует JavaScript. Проблема в том, что если каждый включит свои сценарии без внимания, получающаяся страница будет излишне тяжелой.

Проблема

Пример будет более понятным, и я возьму тот, который я хорошо знаю: мой.

Я разработал плагин WP Photo Sphere, который позволяет пользователям добавлять панорамы в свои посты. Для этого мне понадобились разные файлы JavaScript: библиотека, используемая для отображения этой панорамы, и файл, который извлекает определенные теги, в которых отображаются панорамы. Более того, в этом последнем скрипте я использую jQuery, поэтому мне нужно включить его.

Если бы я не заботился о пользователях, я мог бы вставить эти три сценария на все страницы веб-сайтов, что означает, что посетителям придется загружать эти файлы, даже если страница не нуждается в них.

В настоящее время проблема уже существенна, но она становится еще больше, когда мы думаем о jQuery. Что если два плагина, использующие эту библиотеку, имеют такое поведение? Пользователи не только скачивают бесполезный файл, но и скачивают его дважды!

Чем тяжелее страница, тем дольше она будет загружаться. Сайты, которые слишком долго загружаются, посещаются менее быстрыми сайтами. Если ваш плагин или тема слишком долго загружаются, они не будут использоваться. Это, безусловно, отличная мотивация для оптимизации ваших инструментов, верно?

Неизбежная функция для вставки скриптов

Чтобы избежать проблемы вставки одного и того же файла дважды или более, WordPress предоставляет нам отличную функцию: wp_enqueue_script() . Если вы хотите вставить скрипт, эта функция должна стать вашим лучшим другом.

Как следует из названия, эта функция добавит ваши сценарии в очередь и включит их в нужный момент, в верхний или нижний колонтитул, поэтому в середине страницы не будет добавлен тег script .

При использовании одной функции wp_enqueue_script() требуется как минимум два параметра: имя скрипта и URL-адрес. Например, если я хочу включить скрипт, необходимый для моего плагина, я добавлю эту строку в его основной файл (мы увидим правильные способы сделать это ниже).

 wp_enqueue_script('test', plugin_dir_url(__FILE__) . 'test.js'); 

Тем не менее, три дополнительных параметра дают вам больше контроля над тем, как будет включен ваш скрипт, особенно последний параметр, который является логическим: по умолчанию это логическое значение имеет значение false и ваш скрипт будет включен в тег head , но если если вы установите значение true , тогда ваш скрипт будет включен в нижний колонтитул.

Четвертый параметр полезен, если вы создаете различные версии вашего скрипта: это строка, содержащая номер версии, которая будет объединена до конца URL-адреса. Добавление номера версии гарантирует, что посетители получат правильную версию вашего скрипта, независимо от кэширования.

Третий параметр является одним из наиболее интересных, поскольку он позволяет указывать зависимости для вашего сценария. Например, если вашему скрипту нужна библиотека jQuery, вы можете использовать этот параметр.

 wp_enqueue_script('test', plugin_dir_url(__FILE__) . 'test.js', array('jquery')); 

Как видите, зависимости должны указываться в массиве, даже если есть только одна зависимость. Имя, которое вы указываете в этом массиве, является именем скрипта, зарегистрированного благодаря второй функции: wp_register_script() .

Использование этой второй функции точно такое же, как и использование первой: вы указываете имя скрипта, его URL, его зависимости, номер версии и должны ли они быть включены в нижний колонтитул или нет. Последние три параметра являются необязательными, но остальные обязательны.

 wp_register_script('test', plugin_dir_url(__FILE__) . 'test.js', array('jquery'), '1.0', true); 

Зарегистрировать скрипт не будет его включать. Вам все еще нужно использовать wp_enqueue_script() для включения ваших сценариев, но затем ее использование упрощается: вам нужно только указать имя сценария.

 wp_enqueue_script('test'); 

Возможно, вы спрашиваете себя о полезности wp_register_script() как wp_enqueue_script() может выполнить всю работу. Эта функция предназначена для указания способа включения сценария, но не включает его, если в этом нет необходимости.

Пример будет более понятным, поэтому представьте, что у вас есть два файла JavaScript для включения. Первый файл является библиотекой, а второй файл использует эту библиотеку для выполнения некоторых задач. Для работы библиотеки необходим jQuery, поэтому мы регистрируем ее следующим образом:

 wp_register_script('mylib', plugin_dir_url(__FILE__) . 'lib/mylib.js', array('jquery')); 

В настоящее время библиотека не включена, но если мы хотим включить основной файл, то нам нужно включить эту библиотеку: мы указываем ее как зависимость.

 wp_enqueue_script('myfile', plugin_dir_url(__FILE__) . 'myfile.js', array('mylib')); 

И появляется вся магия. Файл myfile.js включен, но для работы ему нужен файл mylib.js : это работа зависимости, которая будет включать этот файл. Но! Файл mylib.js требует jQuery, поэтому jQuery также включен. Три файла включены в одну строку.

Но это не единственное преимущество функции wp_register_script() : если вы зарегистрируете свои скрипты, другие плагины смогут использовать его. Поэтому, если вы хотите создать различные плагины, один из которых определяет некоторые библиотеки, другие смогут включить их.

Самое большое преимущество функции wp_enqueue_script() состоит в том, что она не будет включать один и тот же скрипт дважды. Например, представьте, что два файла нуждаются в jQuery: эти файлы указывают на его зависимость, а WordPress будет включать библиотеку при включении первого файла. Тогда время для включения второго сценария здесь. WordPress рассматривает jQuery как зависимость, но библиотека уже включена, поэтому включать ее снова не нужно: WordPress этого не сделает.

Такое же поведение появляется при попытке поставить в очередь два сценария с разными именами, но с одинаковым URL. В приведенном ниже примере WordPress включит файл один раз.

 wp_enqueue_script('myfile', plugin_dir_url(__FILE__) . 'myfile.js', array('mylib')); wp_enqueue_script('myotherfile', plugin_dir_url(__FILE__) . 'myfile.js'); 

Однако будьте осторожны: это поведение ограничено: если вы указали номер версии хотя бы в одном wp_enqueue_script() , сценарий будет включен дважды, даже если этот номер версии совпадает. Пример ниже выглядит так же, как предыдущий, но он будет включать файл дважды.

 wp_enqueue_script('myfile', plugin_dir_url(__FILE__) . 'myfile.js', array('mylib'), '1.0'); wp_enqueue_script('myotherfile', plugin_dir_url(__FILE__) . 'myfile.js', array(), '1.0'); 

Тем не менее, в общем, у вас нет никаких причин ставить в очередь один скрипт с разными именами. Но необходимо было выяснить этот случай.

Как видите, эти две функции являются лучшим способом управления зависимостями : вы регистрируете их, а WordPress позаботится об остальном автоматически.

Обратите внимание, что мы использовали имя « jquery », чтобы указать, что мы хотим включить jQuery в наши собственные файлы, но мы не зарегистрировали его. Это имя уже зарегистрировано в WordPress: когда вы загружаете CMS, оно содержит jQuery.

Эта библиотека не единственная: вы можете найти все скрипты, зарегистрированные WordPress на этой странице . Вы можете ставить их в очередь напрямую или через зависимость, и самое интересное в том, что вам не нужно предоставлять файлы, поэтому каждый плагин или тема, использующие эти сценарии, будут использовать одни и те же файлы: в нашем примере, если другой плагин использует jQuery, библиотека будет включена только один раз.

Не ставьте в очередь ваши сценарии везде!

Функция wp_enqueue_script() гарантирует, что скрипт не будет включен дважды и правильно его включит в верхний или нижний колонтитул. Но что если отображаемая страница даже не нуждается в вашем скрипте?

Используйте API Action / Filter

Возьмем пример добавления мультимедийной кнопки в редактор содержимого : файл JavaScript необходим только тогда, когда пользователь находится в редакторе. Фактически, когда обычный посетитель читает статью, он не нуждается в этом сценарии: в том числе он бесполезен и делает страницу более тяжелой.

Вот почему, когда вы хотите включить скрипт на страницу, задайте себе следующий вопрос: когда этот скрипт нужен? Конечно, ответ на этот вопрос будет отличаться в зависимости от того, что делает ваш скрипт.

Но как только вы найдете этот ответ, попробуйте найти соответствующее действие. Кодекс WordPress предоставляет нам список доступных действий , поэтому вы можете найти то, что вы ищете в этом месте. Нашли это? Отлично, создайте новую функцию, которая будет ставить в очередь ваши скрипты, в основном файле вашего плагина или в файле functions.php или вашей теме, например.

 function enqueue_my_scripts() { wp_enqueue_script('script0', plugin_dir_url(__FILE__) . 'lib/myscript.js', array('jquery')); wp_enqueue_script('script1', plugin_dir_url(__FILE__) . 'another-script.js'); } 

Затем запустите его, когда ваше действие будет запущено:

 add_action('the_right_action', 'enqueue_my_scripts'); 

Например, когда мы хотели добавить мультимедийную кнопку, мы использовали действие wp_enqueue_media , которое было идеально:

 add_action('wp_enqueue_media', 'include_media_button_js_file'); 

Если вы попытались найти это действие по ссылке, указанной выше, вы, вероятно, ничего не нашли: на момент написания этой строки wp_enqueue_media не было в списке. Этот список не является исчерпывающим, но это хорошее место для начала.

Если вы не нашли нужного действия, возможно, вы можете найти другое, которое имеет близкое поведение, или, возможно, вам следует попытаться выполнить поиск в фильтрах .

Используйте силу функций WordPress!

Зачастую плагины создаются по определенной причине, которая не может использовать API Action / Filter, или не полностью. Например, плагин может преобразовать некоторые элементы в сообщение, но не во всех из них: шорткоды являются типичным примером этого.

Предположим, что вашему плагину нужны некоторые скрипты, используемые кодом, который заменяет шорткод. Нет действия или фильтра, которые точно нацелены на ваш шорткод. Но есть место, где вы можете быть уверены, что ваш шорткод был найден, где вы можете быть уверены, что ваши скрипты нужны.

Это место является функцией обратного вызова, вызываемой WordPress каждый раз, когда ваш шорткод найден. Вызовите wp_enqueue_script() в эту функцию обратного вызова, и ваши сценарии не будут включены, если в этом нет необходимости.

Но что, если ваш шорткод был найден дважды или более? Ответ прост: ничего.

На самом деле, попробуйте дважды вызвать wp_enqueue_script() с одним и тем же сценарием: этот сценарий будет включен только один раз, и поэтому эта функция является очень хорошим инструментом.

Таким образом, вы можете вставить этот вызов в вашу функцию обратного вызова или в любую другую часть вашего плагина или темы, где вы можете быть уверены, что ваши скрипты нужны: даже если они нужны несколько раз, они будут включены только один раз.

Обратите внимание, что в зависимости от того, где wp_enqueue_script() ваш wp_enqueue_script() , может быть слишком поздно попросить WordPress включить их в тег head : вашим единственным выбором будет нижний колонтитул. Если ваш сценарий должен быть в теге head по непонятной причине, подумайте об этом.

Может быть, у вас есть вопрос сейчас: когда уже слишком поздно?

Каждая тема должна использовать две специальные функции: wp_head() и wp_footer() . Когда вызывается первый, WordPress автоматически добавит все строки, необходимые в теге head : если вы попросили включить ваши скрипты в тег head , они будут включены при wp_head() , поэтому, если вы спросите это включение после wp_head() ваши скрипты не будут включены в тег head .

Но WordPress умный, и ваши скрипты все равно будут включены: вы сможете получить их в нижнем колонтитуле, когда wp_footer() функция wp_footer() и когда включены скрипты, которые должны быть включены в это место.

Итак, у вас есть ответ: если вы абсолютно хотите включить свой скрипт в тег head , попросите включить его перед wp_head() который должен находиться в конце тега head в теме. wp_footer() должен быть в самом конце документа, до конца тега body .

Вывод

Ваши сценарии полезны для того, что ваш плагин или тема делает в определенном месте, но включение их в страницы, где они не нужны, сделает эти же страницы излишне тяжелыми.

WordPress предоставляет нам несколько инструментов, позволяющих нам правильно включать наши сценарии, только когда они необходимы. Единственный вопрос, который нужно задать, когда вы хотите использовать эти инструменты, заключается в следующем: когда или где нужны мои сценарии? Остальное зависит от ответа: найти действие или фильтр, поместить wp_enqueue_script() в нужную функцию, используя мощь этой функции, или объединить все это.

Вы можете получить некоторые примеры, описанные выше, в тестовом плагине, доступном прямо здесь . Он ставит в очередь скрипт и «библиотеку» и создает шорткод, используя другой бесполезный скрипт.