Когда использовать add_action('init') против add_action('wp_enqueue_scripts')
В файле functions.php моей темы я использую add_action для контроля над тем, где загружается jQuery (в футере вместе с другими скриптами темы).
Проблема в том, что когда я использую add_action('wp_enqueue_scripts'), он срабатывает только если не загружены плагины. Однако метод add_action('init') работает во всех случаях.
Насколько я помню, add_action('wp_enqueue_scripts') предпочтительнее в этом случае. Если это так, как можно заставить его работать во всех случаях?
В файле functions.php
//if(!is_admin()){add_action('init', 'my_theme_init');} //ЭТО РАБОТАЕТ ВСЕГДА
//add_action('wp_enqueue_scripts', 'my_theme_init'); //ЭТО РАБОТАЕТ ТОЛЬКО КОГДА НЕТ ПЛАГИНОВ
if(!is_admin())
{
require_once(TEMPLATEPATH . '/functions_public.php');
}
В файле functions_public.php
function my_theme_init()
{
/* ПРЕДОТВРАЩАЕМ ДУБЛИРОВАНИЕ JQUERY ИЗ ПЛАГИНОВ
**************************************************/
wp_deregister_script('jquery');
/* ЗАГРУЖАЕМ ЛОКАЛЬНУЮ КОПИЮ JQUERY WORDPRESS И ПОЛЬЗОВАТЕЛЬСКИЕ СКРИПТЫ ТЕМЫ В ФУТЕР
***********************************************/
wp_register_script('jquery', get_bloginfo('template_directory').'/scripts.mythemescripts.js',false,false,true);
wp_enqueue_script('jquery');
}
Второй метод, использующий add_action('wp_enqueue_scripts'), по-видимому, не выполняется в условиях, когда присутствует плагин, который прописывает зависимости скриптов в тему.

Многие разработчики плагинов делают вещи неправильно. Правильный способ — использовать хук wp_enqueue_scripts
, как вы и пытаетесь сделать.
Однако вот порядок выполнения хуков в типичном запросе:
- muplugins_loaded
- registered_taxonomy
- registered_post_type
- plugins_loaded
- sanitize_comment_cookies
- setup_theme
- load_textdomain
- after_setup_theme
- auth_cookie_malformed
- auth_cookie_valid
- set_current_user
- init
- widgets_init
- register_sidebar
- wp_register_sidebar_widget
- wp_default_scripts
- wp_default_stypes
- admin_bar_init
- add_admin_bar_menus
- wp_loaded
- parse_request
- send_headers
- parse_query
- pre_get_posts
- posts_selection
- wp
- template_redirect
- get_header
- wp_head
- wp_enqueue_scripts
- wp_print_styles
- wp_print_scripts
- ... и многое другое
Дело в том, что изначально разработчикам говорили использовать хук init
для подключения скриптов. До того, как появился хук wp_enqueue_script
, это считалось "правильным" способом, и руководства, пропагандирующие эту практику, до сих пор можно найти в интернете, вводя в заблуждение даже хороших разработчиков.
Я рекомендую разделить вашу функцию на две части. Используйте wp_deregister_script
/wp_register_script
в хуке init
, а для непосредственного подключения jQuery используйте хук wp_enqueue_scripts
.
Это позволит вам оставаться в рамках "правильного" подхода к подключению скриптов и защитит от сотен разработчиков, которые до сих пор "делают это неправильно", заменяя jQuery на вашу объединенную версию перед добавлением в очередь.
Также стоит добавить ваш хук init
с высоким приоритетом:
add_action( 'init', 'swap_out_jquery', 1 );
function swap_out_jquery() {
// ...
}

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

Важное замечание о priority
при добавлении действий. Все зависит от того, как вы понимаете приоритет. Если вы хотите, чтобы ваш код выполнялся "первым", то лучше использовать меньшее число — более высокий приоритет в порядке выполнения очереди. Но если вы хотите, чтобы эффект от вашей функции имел приоритет над другими, вам нужно, чтобы она выполнялась позже — то есть более высокий приоритет по "эффекту". В данном случае, вероятно, вам нужно большее число. Хотя, как отмечает предыдущий комментатор, в замене официальной версии jQuery мало смысла.

Здесь есть несколько взаимосвязанных проблем.
- Правильный хук для подключения скриптов —
wp_enqueue_scripts
- Чтобы выводить скрипты в подвале через
wp_enqueue_script()
, установите параметр$footer
вtrue
- Ваши вызовы
add_action( $hook, $callback )
не должны быть обёрнуты во что-либо; они должны выполняться напрямую изfunctions.php
- Проверки условия
is_admin()
следует размещать внутри вашего коллбэка - Не следует отменять регистрацию скриптов, входящих в ядро WordPress, из темы, по любой причине. Даже если ваша цель — объединение скриптов, это территория плагинов.
- Если вам необходимо отменить регистрацию jQuery, то хук
wp_enqueue_scripts
уже слишком поздно. Разделите ваш код отмены регистрации/регистрации на коллбэк, подключённый к хукуinit
. - Название какого-либо другого скрипта "jquery" — также не лучшая практика. Лучшим решением будет просто удалить jQuery из очереди, а затем загрузить ваш собственный скрипт.
- Убедитесь, что установили низкий приоритет для вашего коллбэка, чтобы переопределить плагины
- Используйте
get_template_directory()
вместоTEMPLATEPATH
Объединяя всё вместе:
<?php
function wpse55924_enqueue_scripts() {
if ( ! is_admin() ) {
// Удалить jQuery из очереди
wp_dequeue_script( 'jquery' );
// Зарегистрировать/добавить в очередь пользовательский скрипт, включающий jQuery
wp_register_script( 'mythemescripts', get_template_directory_uri() . '/scripts.mythemescripts.js', false, false, true );
wp_enqueue_script( 'mythemescripts' );
}
}
add_action( 'wp_enqueue_scripts', 'wpse55924_enqueue_scripts', 99 );
Но снова: это не самый лучший подход. Лучшим решением будет просто удалить вызовы add_action() в плагинах, которые отменяют регистрацию jQuery из ядра — или использовать плагины, которые не делают чего-то столь безответственного, как замена встроенного в ядро jQuery.

OP объединяет версию jQuery, поставляемую с WordPress, с другими скриптами программно, чтобы его тема делала только один HTTP-запрос для загрузки всех JS-файлов. Таким образом, пользовательские скрипты действительно содержат jQuery и не сломают ничего при такой загрузке. Переопределение зарегистрированного обработчика 'jquery' необходимо, чтобы предотвратить двойную загрузку jQuery — один раз в объединённом JS-файле и ещё раз плагинами, которые пытаются загрузить jQuery самостоятельно.

Семантически и практически _doing_it_wrong()
называть что-то, что не является чистым jQuery, "jQuery". Также: сам jQuery можно просто удалить из очереди, чтобы гарантировать, что он не загрузится дважды. Вызов wp_dequeue_script()
просто должен происходить с достаточным приоритетом, чтобы гарантировать, что никто не поставит его в очередь после этого.

Этот ответ не совсем по вашему вопросу, но в вашем коде есть ещё одна проблема.
Вам никогда не нужно и не следует использовать:
wp_enqueue_script('jquery');
Если вы хотите использовать jQuery, предоставляемый WordPress, то лучший способ сделать это - при подключении вашего собственного JavaScript-файла указать jQuery в качестве зависимости. Таким образом, WordPress сам позаботится о его загрузке, и вам не нужно подключать его вручную.
Пример:
wp_enqueue_script( 'myjslib-handle', get_stylesheet_directory_uri() . '/js/myfile.js', array('jquery'), '1.0.0', true );
array('jquery') в приведённом выше коде - это параметр, который указывает на необходимость загрузки jQuery в качестве зависимости.
