Когда использовать add_action ('init') против add_action ('wp_enqueue_scripts')

10

В файле 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');} //THIS WORKS ALL THE TIME
//add_action('wp_enqueue_scripts', 'my_theme_init'); //THIS ONLY WORKS WHEN NO PLUGINS PRESENT

if(!is_admin())
{
    require_once(TEMPLATEPATH . '/functions_public.php');   
}

В functions_public.php

function my_theme_init()
{

/* PREVENT DUPLICATE COPIES OF JQUERY FROM PLUGINS
**************************************************/
wp_deregister_script('jquery');

/* LOAD THE LOCAL WORDPRESS COPY OF JQUERY AND THEME CUSTOM SCRIPTS IN THE FOOTER
***********************************************/
wp_register_script('jquery', get_bloginfo('template_directory').'/scripts.mythemescripts.js',false,false,true);

wp_enqueue_script('jquery');

}

Второй метод, использующий add_action ('wp_enqueue_scripts'), по-видимому, не выполняется в условиях, когда присутствует плагин, который записывает зависимости скрипта в тему.

N2Mystic
источник
5
Пожалуйста, не регистрируйте свою собственную копию jquery - используйте версию, поставляемую с WordPress, иначе вы в конечном итоге сломаете плагины :)
Стивен Харрис,
Я согласен, на самом деле я использую тот, который поставляется с JQuery. Я просто загружаю его в один файл .js (mythemescripts.js) вместе с другими файлами js, которые нужны моей теме, чтобы уменьшить количество http-запросов.
N2Mystic
Во всех браузерах, когда скрипт запрашивается с вашего сайта один раз, он кэшируется локально. У вас будет только дополнительный HTTP-запрос при первой загрузке страницы. Если вы объедините все сценарии в один, вы будете вынуждены изменять это каждый раз, когда WP выпускает обновление с новой версией jQuery. Это == техническое обслуживание кошмар.
EAMann
2
@EAMann, когда тема впервые устанавливается и каждый раз после этого сохраняется страница параметров моей темы, я переписываю mythemescripts.js, загружая в нее последнюю копию библиотеки jquery. Если пользователь обновляет свою версию WP, моя подпрограмма опций темы загружает jquery, который идет с этим. Это всегда актуально.
N2Mystic
Проблема по-прежнему возникает, когда вызов jquery содержится в теле документа перед нижним колонтитулом. Очевидно, jQuery (документ) .ready запускается до того, как скрипт .js загружается в нижний колонтитул.
N2Mystic

Ответы:

26

Многие разработчики плагинов не делают все правильно. Правый путь зацепить , чтобы , 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
  • в этом
  • 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
  • в.ч.
  • 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хуке и используйте wp_enqueue_scriptsхук, когда вы на самом деле ставите jQuery в очередь.

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

Вы также захотите добавить свой initхук с высоким приоритетом:

add_action( 'init', 'swap_out_jquery', 1 );
function swap_out_jquery() {
    // ...
}
EAMann
источник
2
Я собирался порекомендовать это, но потом понял, что OP фактически отменяет регистрацию jQuery, а затем полностью регистрирует другой скрипт и называет его «jquery». Я не думаю, что это хорошая практика, чтобы поощрять, и думаю, что лучшим способом было бы просто полностью исключить jQuery из очереди , а затем поставить в очередь пользовательский сценарий, используя пользовательский дескриптор .
Чип Беннетт
Укажите на примечание о priorityдобавлении действий. Все зависит от того, как вы оцениваете приоритет. Если вы хотите, чтобы ваш выполнялся «первым», то чем меньше число, тем лучше - более высокий приоритет в порядке очереди выполнения. Но если вы хотите, чтобы эффект вашей функции имел приоритет над другими, вы захотите, чтобы он выполнялся позже - так что более высокий приоритет - «эффект». И в этом случае это, вероятно, большее число, которое вы хотели бы. Несмотря на то, что выгрузка RTM-версии jquery не имеет смысла, как предполагает предыдущий комментатор.
Пол Г.
3

Здесь есть несколько вопросов, которые взаимосвязаны.

  1. Правильный хук действия для постановки в очередь скриптов wp_enqueue_scripts
  2. Чтобы распечатать скрипты в нижнем колонтитуле wp_enqueue_script(), установите для $footerпараметра значениеtrue
  3. Ваши add_action( $hook, $callback )звонки ни в коем случае не должны быть обернуты; пусть они выполняются прямо изfunctions.php
  4. Вы должны поместить свои is_admin()условные проверки в ваш обратный вызов
  5. Вы не должны отменять регистрацию основных сценариев из Темы по любой причине. Даже если ваша цель - объединение сценариев, это территория плагина .
  6. Если вы должны отменить регистрацию jquery, тогда wp_enqueue_scriptsуже слишком поздно . Разделите ваш код отмены регистрации / регистрации в обратный вызов, подключенный к init.
  7. Называть какой-то другой скрипт "jquery" также, вероятно, не очень хорошая практика. Лучше было бы просто снять jQuery с очереди и загрузить свой собственный скрипт.
  8. Убедитесь, что ваш обратный вызов имеет низкий приоритет, поэтому вы переопределяете плагины
  9. Используйте, get_template_directory()а неTEMPLATEPATH

Собираем все вместе:

<?php
function wpse55924_enqueue_scripts() {
    if ( ! is_admin() ) {

        // Dequeue jQuery
        wp_dequeue_script( 'jquery' );

        // Register/enqueue a custom script, that includes 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, распространяемую в WP, с некоторыми другими сценариями, так что его тема делает только один HTTP-запрос для загрузки всех файлов JS. Таким образом, пользовательские скрипты содержат jQuery и ничего не сломают, если загружены таким образом. Перезапись зарегистрированного дескриптора 'jquery' необходима, чтобы предотвратить загрузку jQuery дважды - один раз в объединенный файл JS и снова любыми плагинами, пытающимися поставить в очередь jQuery самостоятельно.
EAMann
Семантически и практически _doing_it_wrong()называть то, что не просто jQuery, «jQuery». Также: сам jQuery можно просто снять с очереди , чтобы он не загружался дважды. wp_dequeue_script()Вызов просто должно произойти с достаточным приоритетом , чтобы обеспечить , что ничто его ставит в очередь позже.
Чип Беннетт