Знание правильного способа включения JavaScript и CSS файлов в ваши WordPress темы и плагины очень важно для дизайнеров и разработчиков. Если вы не будете следовать лучшим подходам, вы рискуете вступить в конфликт с другими темами и плагинами и потенциально создаете проблемы, которых можно было бы легко избежать. Эта статья может быть источником информации о том, как уживаться с JavaScript и CSS в WordPress.
Правильный подход к делу
Если вы когда-либо разрабатывали тему или плагин для WordPress или работали с созданными кем-то — вы, скорее всего, пробовали несколько разных методов включения JavaScript и CSS. Несмотря на то, что есть несколько методов, которые могут работать в некоторых обстоятельствах, есть один основной метод, рекомендованный WordPress Codex. Благодаря этому методу вы сможете быть уверенным, что тема или плагин будет работать в любом случае (при условии, что и другие будут писать код правильно).
Есть некоторое недопонимание в том, что именно Codex говорит по этому поводу, и я постараюсь помочь разъяснить этот вопрос.
Что в коробке?
Когда вы скачали WordPress, выбор распространенных JavaScript библиотек, которые вы можете использовать для вашей JavaScript разработки, уже включен. Список включенных библиотек можно найти в статье WordPress Codex wp_enqueue_script.
Все эти библиотеки включены, но по умолчанию WordPress загружает только те, которые ему необходимы, и только тогда, когда они нужны ему. Если вы пишете JavaScript, который использует одну из этих библиотек, вам нужно сказать WordPress, что вашему скрипту сначала нужно загрузить библиотеку.
Знает ли WordPress о вашем скрипте и его потребностях?
Вот некоторые вещи, о которых вам нужно подумать, когда вы пишете JavaScript для WordPress:
- Есть ли уже включенная библиотека, которую я могу использовать?
- Могу ли я использовать включенную версию?
- Нужно ли мне загружать мой скрипт в клиентскую и администраторскую часть?
- На каких страницах клиентской и администраторской части мне нужно загружать мой скрипт?
Ответы на эти вопросы помогут вам узнать, что вам нужно сделать, чтобы зарегистрировать и загрузить ваш скрипт. Это происходит с помощью WordPress функции wp_register_script, и вот как ее нужно использовать согласно WordPress Codex:
wp_register_script( $handle, $src, $deps, $ver, $in_footer );
Так что это за переменные и нужны ли они нам все время? Это описано на странице Codex, так что я коротко опишу:
- $handle — ее вы будете использовать для того, чтобы ссылаться на этот конкретный скрипт, когда вам нужно будет добавить его в очередь, и вам нужно вставлять эту переменную в самом конце.
- $src — путь к исходному файлу вашего плагина или темы.
- $deps — массив, который включает $handle для всех скриптов, которые могут понадобиться вашему скрипту (то есть, зависимости).
- $ver — номер версии вашего скрипта, которая может быть использована для уничтожения кэша. По умолчанию, WordPress будет использовать свою версию в качестве версии вашего скрипта.
- $in_footer — вы хотите, чтобы ваш скрипт загружался в подвале? Установите значение этой переменной true или false. По умолчанию оно установлено в false, так что скрипт загружается в шапке, где wp_head(), а если вы укажете true, скрипт будет загружаться в подвале, где в теме указан wp_footer().
Что такое “уничтожение кэша”?
Браузеры запоминают, какие скрипты и таблицы стилей они загружали для конкретного сайта, основываясь на URL скрипта и таблиц стилей. Если вы измените URL, даже просто добавив туда запрос, браузер предположит, что это новый файл, и загрузит его.
Перейдем к примерам
Вот простой пример подключения скрипта:
function wptuts_scripts_basic() { // Register the script like this for a plugin: wp_register_script( 'custom-script', plugins_url( '/js/custom-script.js', __FILE__ ) ); // or // Register the script like this for a theme: wp_register_script( 'custom-script', get_template_directory_uri() . '/js/custom-script.js' ); // For either a plugin or a theme, you can then enqueue the script: wp_enqueue_script( 'custom-script' ); } add_action( 'wp_enqueue_scripts', 'wptuts_scripts_basic' );
Сначала мы регистрируем скрипт, так что теперь WordPress знает, с чем мы работаем. Путь к нашему JavaScript файлу может быть разным, в зависимости от того, пишем мы тему или плагин, так что выше я включил примеры и того, и другого. Затем мы добавим его в очередь на добавление в HTML для страницы, когда она будет сгенерирована, по умолчанию — в блоке <head>, в месте вызова в теме wp_head().
Вот что мы получим из этого простого примера:
<script type="text/javascript" src="http://yourdomain.com/wp-content/plugins/yourplugin/js/custom-script.js?ver=3.3.1"></script>
Теперь, если ваш скрипт базируется на одной из библиотек, включенных в WordPress, например jQuery, вы можете сделать простое изменение в коде:
function wptuts_scripts_with_jquery() { // Register the script like this for a plugin: wp_register_script( 'custom-script', plugins_url( '/js/custom-script.js', __FILE__ ), array( 'jquery' ) ); // or // Register the script like this for a theme: wp_register_script( 'custom-script', get_template_directory_uri() . '/js/custom-script.js', array( 'jquery' ) ); // For either a plugin or a theme, you can then enqueue the script: wp_enqueue_script( 'custom-script' ); } add_action( 'wp_enqueue_scripts', 'wptuts_scripts_with_jquery' );
Примечание: По умолчанию, jQuery загружается с noConflict, чтобы предотвратить конфликты с другими библиотеками (например, Prototype). Посмотрите раздел noConflict в Codex, если вы не знаете, как это работает.
Так что мы здесь сделали? Мы просто добавили массив с указателем ‘jquery‘ в качестве зависимости. Здесь используется массив, так как у вашего скрипта может быть несколько зависимостей. Если ваш скрипт использует jQuery и jQuery UI, вы можете добавить jQuery UI в ваш массив зависимостей, например так:
array( ‘jquery’, ‘jquery-ui-core’)
Теперь результат изменился, и мы видим, что jQuery также был добавлен в <head>страницы.
<script type='text/javascript' src='http://yourdomain.com/wp-includes/js/jquery/jquery.js?ver=1.7.1'></script> <script type='text/javascript' src='http://yourdomain.com/wp-content/plugins/yourplugin/js/custom-script.js?ver=3.3.1'></script>
Попробуем пример со всеми прибамбасами:
function wptuts_scripts_with_the_lot() { // Register the script like this for a plugin: wp_register_script( 'custom-script', plugins_url( '/js/custom-script.js', __FILE__ ), array( 'jquery', 'jquery-ui-core' ), '20120208', true ); // or // Register the script like this for a theme: wp_register_script( 'custom-script', get_template_directory_uri() . '/js/custom-script.js', array( 'jquery', 'jquery-ui-core' ), '20120208', true ); // For either a plugin or a theme, you can then enqueue the script: wp_enqueue_script( 'custom-script' ); } add_action( 'wp_enqueue_scripts', 'wptuts_scripts_with_the_lot' );
Так, теперь я добавил версию и указал, что скрипт нужно загружать в подвале. В качестве версии я решил использовать сегодняшнюю дату, потому что так проще отслеживать, но вы можете использовать любой подход к нумерации версий. Результат этого примера не особо отличается, jQuery в <head>, а наш скрипт вместе с jQuery UI — прямо перед </body>, например:
<head> ... <script type='text/javascript' src='http://yourdomain.com/wp-includes/js/jquery/jquery.js?ver=1.7.1'></script> ... </head> <body> ... <script type='text/javascript' src='http://yourdomain.com/wp-includes/js/jquery/ui/jquery.ui.core.min.js?ver=1.8.16'></script> <script type='text/javascript' src='http://yourdomain.com/wp-content/plugins/yourplugin/js/custom-script.js?ver=20120208'></script> </body>
Расставляем приоритеты
Некоторые предпочитают не использовать правильные методы постановки в очередь, потому что им кажется, что у них будет меньше контроля над порядком загрузки скриптов. Например, в теме, которая использует modernizr, автор темы, возможно, захочет убедиться в том, что modernizr загружается заранее.
Кое-что, о чем я не упомянул раньше — детали того, как работает функция add_action, поскольку здесь у нас может быть немного влияния на порядок вещей. Вот использование функции согласно странице WordPress Codex:
add_action( $tag, $function_to_add, $priority, $accepted_args );
Обратите внимание, что часто используются только параметры $tag и $function_to_add. Параметр $priority по умолчанию равен 10, а параметр $accepted_args — 1. Если мы хотим, чтобы наши скрипты или стили были вызваны раньше, мы просто уменьшаем значение $priority. Например:
function wptuts_scripts_important() { // Register the script like this for a plugin: wp_register_script( 'custom-script', plugins_url( '/js/custom-script.js', __FILE__ ) ); // or // Register the script like this for a theme: wp_register_script( 'custom-script', get_template_directory_uri() . '/js/custom-script.js' ); // For either a plugin or a theme, you can then enqueue the script: wp_enqueue_script( 'custom-script' ); } add_action( 'wp_enqueue_scripts', 'wptuts_scripts_important', 5 );
Результат будет таким же, как мы видели раньше, но он появится в HTML документе раньше.
Переопределение стандартных библиотек и использование сетей доставки контента
Возможно, вы захотите использовать другую версию включенной в WordPress библиотеки. Возможно, вы захотите использовать самую новую версию или вы не хотите ждать следующего релиза WordPress для того, чтобы использовать последнюю стабильную версию jQuery. Другая причина — возможно, вы захотите воспользоваться Google CDN версией библиотеки.
Важно обратить внимание, что это может быть сделано только в плагинах или темах на сайтах, которые вы будете лично поддерживать. Любые плагины или темы, которые вы выпускаете для публичного использование, должны использовать включенные в WordPress библиотеки.
Я слышу, как вы спрашиваете: “Почему?!” Простая причина — вы не контролируете те сайты. Вы не знаете, какие еще плагины и темы могут быть там использованы, и вы не знаете, как часто они будут обновлять ваш плагин или тему. Использование библиотек из пакета WordPress — наиболее безопасный вариант.
Теперь, если вы действительно хотите сделать это на сайте, которым вы управляете, вот как это можно сделать:
function wptuts_scripts_load_cdn() { // Deregister the included library wp_deregister_script( 'jquery' ); // Register the library again from Google's CDN wp_register_script( 'jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js', array(), null, false ); // Register the script like this for a plugin: wp_register_script( 'custom-script', plugins_url( '/js/custom-script.js', __FILE__ ), array( 'jquery' ) ); // or // Register the script like this for a theme: wp_register_script( 'custom-script', get_template_directory_uri() . '/js/custom-script.js', array( 'jquery' ) ); // For either a plugin or a theme, you can then enqueue the script: wp_enqueue_script( 'custom-script' ); } add_action( 'wp_enqueue_scripts', 'wptuts_scripts_load_cdn' );
Сначала я отменяю регистрацию включенной версии библиотеки, иначе могут возникнуть конфликты между разными версиями. Затем регистрируем альтернативную версию, используя тот же указатель. Я решил присвоить версии значение null (он уже содержится в URL) и определил, что отображаться будет не в подвале. Остальной код будет тот же, потому что мы зависим от скрипта, который использовал указатель ‘jquery‘. Результат, который мы получим, будет выглядеть примерно так:
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script> <script type='text/javascript' src='http://yourdomain.com/wp-content/plugins/yourplugin/js/custom-script.js?ver=3.3.1'></script>
Примечание: Одна из причин считать это плохой идеей для плагинов или тем для общественного использования — все другие плагины и темы, использованные на этом сайте, теперь будут использовать эту версию jQuery. Также заново зарегистрированная версия jQuery не содержит noConflict, так что если любой другой скрипт плагина или темы использует, например, Prototype, это все поломает.
Не жадничайте
Пока мы не упоминали ничего о том, как все это делать в админ части, только с клиентской стороны. Основное отличие в том, какой action использовать. Вместо
add_action( ‘wp_enqueue_scripts’, ‘wptuts_scripts_basic’ );
который мы использовали для клиентской части, для администратора будет
add_action( ‘admin_enqueue_scripts’, ‘wptuts_scripts_basic’ );
Что важно сделать и для клиентской, и для админ части — выбирать, на каких страницах загружать ваши скрипты. Если у вашего плагина или темы есть скрипт, который делает что-то только на одной клиентской или админ странице, например, на странице настроек темы или странице с конкретным виджетом, вам нужно загрузить ваш скрипт только на этой странице. Нет смысла загружать скрипты на страницах, на которых они не используются!
В WordPress Codex есть отличный пример того, как загружать скрипты только на страницах плагина. Поскольку плагины и темы могут различаться в написании кода, я не буду углубляться в том, как выбирать, на каких страницах грузить скрипты, но было важно это упомянуть, чтобы вы знали это, когда будете писать код.
Со скриптами закончили, теперь стили
Процесс для стилей практически такой же, как для скриптов. Все происходит с помощью WordPress функции wp_register_style, и вот ее использование согласно WordPress Codex:
wp_register_style( $handle, $src, $deps, $ver, $media );
Обратите внимание, что единственная разница между wp_register_script и wp_register_style — то, что вместо параметра $in_footer у нас параметр $media. Этот параметр может быть установлен в значение ‘all‘, ‘screen‘, ‘handheld‘ и ‘print‘, или любой другой медиа тип, распознаваемый W3C.
Так что пример того, как может быть вызван стиль, может быть таким:
function wptuts_styles_with_the_lot() { // Register the style like this for a plugin: wp_register_style( 'custom-style', plugins_url( '/css/custom-style.css', __FILE__ ), array(), '20120208', 'all' ); // or // Register the style like this for a theme: wp_register_style( 'custom-style', get_template_directory_uri() . '/css/custom-style.css', array(), '20120208', 'all' ); // For either a plugin or a theme, you can then enqueue the style: wp_enqueue_style( 'custom-style' ); } add_action( 'wp_enqueue_scripts', 'wptuts_styles_with_the_lot' );
Это достаточно сложный пример, который использует большинство параметров, и вот что получится на выходе:
<link rel='stylesheet' id='custom-style-css' href='http://yourdomain.com/wp-content/plugins/yourplugin/css/custom-style.css?ver=20120208' type='text/css' media='all' />
Почему не все так делают?
Хороший вопрос. Еще один вопрос, который вы могли бы задать, это «Почему вы думаете, что это правильный способ, а не просто ваше предпочтение?» Обычно ответ в том, что это подход, рекомендованный WordPress. Его использование позволяет быть уверенными, что любая комбинация плагинов и тем будет счастливо работать вместе без проблем.
Я видел несколько тем и фреймворков, которые используют теги <script></script> и <link /> в своих файлах header.php и даже в footer.php для загрузки скриптов и стилей для темы. Нет причины для того, чтобы делать это так. Как я показал раньше, вполне можно задать в приоритет скрипты и стили и указать, должны они быть загружены в шапке или в подвале, сделать все это удобно и надежно в вашем functions.php. Выгода в том, что ваша тема или фреймворк будет работать с более широким спектром других плагинов и тем-потомков.
В одном примере jQuery загружался с использованием тегов <script></script>, что в принципе могло бы работать хорошо, но это может привести к тому, что jQuery может загрузиться дважды! Загрузка jQuery таким образом не остановит WordPress от загрузки своей версии jQuery для других плагинов, поскольку версии WordPress по умолчанию в режиме noConflict, и плагин может определить его как зависимость. Так что теперь у вас будет jQuery, который работает и в режиме noConflict и $, и также возможно сломает любой плагин, который использует библиотеку Prototype.
Заключение
WordPress — фантастическая система, и она была разработана с умом. Если есть механизм, который был создан для чего-то, — лучше использовать его. Разрабатывая ваши плагины и темы, постарайтесь помнить, что нужно писать с умом и думать о других.
Что вы думаете об использовании wp_enqueue_script и связанных с ней функциях и action? Знаете ли вы примеры неправильного использования? Есть ли у вас причина не следовать изложенным выше советам? Поделитесь своими мыслями в комментариях.
Источник