Что такое хуки wordpress. Полезные советы по работе с хуками WordPress. Введение в инициализационные хуки

Если вы плохо знакомы с хуками, эта статья поможет вам. Приведенные в статье примеры взяты из ядра WordPress, а также из собственного многолетнего опыта работы разработчиком плагинов.


Хуки WordPress — это функция, которая позволяет расширять возможности плагины и темы без риска их сломать. Что такое хуки?

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

Хук «customize» называется «фильтром». Фильтр позволяет изменять или настраивать значение и возвращать его в новой форме. Вот некоторые примеры:

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

Для фильтра важна не только позиция, но и возвращаемые значения. WordPress имеет фильтр почти для каждого значения, которое обрабатывает.

Элементы процедуры хука

Используем в качестве примера действия хук wp_head , а в качестве примера фильтра хук the_content .

Хук (существительное)

Сам хук — это указание того, когда и где происходит магия. Представьте себе, что это крюк, который альпинист вбил в поверхность скалы. Крюк имеет определенную позицию. Если другие альпинисты захотят двигаться в этом направлении, они могут использовать его.
Хуки действий вызываются с помощью функции do_action:

do_action("wp_head");

Хуки вызываются с помощью apply_filters() :

$content=apply_filters("the_content",$content);

Как видите, нам нужно перехватить данные из фильтра.

Действия и фильтры

Следующий элемент в процедуре хука — это действие или фильтр. Это функция, которую вы определяете, чтобы сделать или отфильтровать что-то. Это альпинист, который готов использовать любой крюк, чтобы взобраться немного выше.
Действие, которое запускается в wp_head — это noindex() .

functionnoindex(){ // Если блог не является публичным, указать роботам проходить мимо. if("0"==get_option("blog_public")) wp_no_robots(); }

Хук проверяет, отключена ли настройка видимости для поисковых систем. Если это так, wp_no_robots() добавляет мета тег robots , указывающий поисковым системам не индексировать сайт.
Примером фильтра для the_content является wpautop() . Он отвечает за перенос абзацев в теге

И использование тега
для разрывов строк.

functionwpautop($pee,$br=true){ // … return$pee; }

В отличие от действия, функции фильтра требуется хотя бы один аргумент. Он должен быть возвращен.

Хук (глагол)

В процедуре хука WordPress нужно указать, для чего именно предназначен хук. Это означает, что мы должны привязать функцию (глагол) к крюку (существительному). Это делается с помощью функции, которая часто неправильно называется «хуком».
Для хука wp_head и действия noindex() связь устанавливается с помощью этой строки кода:

add_action("wp_head","noindex",1);

Третий параметр является приоритетом. Мы рассмотрим его ниже.
Включение wpautop() в the_contentо осуществляется с помощью этой строки:

add_filter("the_content","wpautop");

Это основные принципы процедуры хука. В следующих разделах мы рассмотрим их более подробно.

Вы уже используете эти хуки

Даже если вы «просто» изменяете тему или добавляете код в файл functions.php , вы уже используете действия и фильтры.

WP_HEAD

Рассмотрим раздел заголовка темы Twenty Fifteen, который можно найти в файле wp-content/themes/twentyfifteen/header.php .

Между открывающимся и закрывающимся тегами размещается не так уж много кода, но просмотрите исходный код страницы в браузере. Вы увидите там различные мета элементы, включая тег .
Элементы, которые могут отсутствовать в файле header.php , добавляются функцией wp_head() . Если вы используете среду разработки, просмотрите ее содержимое.

/** * Запуск действия wp_head * * @since 1.2.0 */ functionwp_head(){ /** * Выводим через front-end скрипт или данные в теге head. * * @since 1.5.0 */ do_action("wp_head"); }

Единственное, что делает функция wp_head() , это выводит хук wp_head . Это означает, что тема может использовать do_action(‘wp_head’) , вместо wp_head () .
Этот хук уже используется ядром. Вот некоторые действия, которые WordPress подключает к этому хуку по умолчанию:

add_action("wp_head","_wp_render_title_tag",1); add_action("wp_head","wp_enqueue_scripts",1); add_action("wp_head","feed_links",2); add_action("wp_head","feed_links_extra",3); add_action("wp_head","rsd_link"); add_action("wp_head","wlwmanifest_link"); add_action("wp_head","adjacent_posts_rel_link_wp_head",10,0); add_action("wp_head","locale_stylesheet"); add_action("wp_head","noindex",1); add_action("wp_head","print_emoji_detection_script",7); add_action("wp_head","wp_print_styles",8); add_action("wp_head","wp_print_head_scripts",9); add_action("wp_head","wp_generator"); add_action("wp_head","rel_canonical"); add_action("wp_head","wp_shortlink_wp_head",10,0); add_action("wp_head","wp_site_icon",99);

Среди них — действие noindex() , а также (начиная с версии WordPress 4.1) вызов _wp_render_title_tag() , который генерирует тег title .

Контент

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

functionthe_content($more_link_text=null,$strip_teaser=false){ $content=get_the_content($more_link_text,$strip_teaser); // … $content=apply_filters("the_content",$content); $content=str_replace("]]>","]]>",$content); echo$content; }

По умолчанию к функции the_content уже подключено несколько фильтров.

add_filter("the_content","wptexturize"); add_filter("the_content","convert_smilies"); add_filter("the_content","convert_chars"); add_filter("the_content","wpautop"); add_filter("the_content","shortcode_unautop"); add_filter("the_content","prepend_attachment");

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

Уроки использования the_content

Вот два примера того, как неправильное использование хука приводит к сбою в работе функции.
Тело функции the_content() также содержит вызов get_the_content() . Я видел, как второй использовался вместо первого в нескольких темах. Но таким образом сам хук отключается, и многие функции не будут работать.
Если вы подключаетесь к the_content , то имейте в виду, что он используется не только на страницах контента, но и на страницах списков. Например, в архивах, а также на главной странице.

Параметры в процедуре хука

Основные параметры, которые нужны — это имя хука, имя функции, приоритет и аргументы, которые ей передаются.
Вот как выглядит вызов add_filter :

add_filter($tag,$function,$priority,$accepted_args);

Имена хуков ($teg)

Вы не сможете ничего сделать с именами хуков, которые используются в ядре WordPress, плагинах или темах оформления. Но при задании собственных имен нужно придерживаться нескольких принципов.
Имя действия должно включать в себя место, а фильтр-место и значение, которое будет изменено.
В качестве примеров действий можно привести wp_head и wp_footer , которые называются в соответствии с местом их расположения. Также часто используются префиксы или суффиксы. Например: before , pre , begin , after и end .

Функция wp_delete_post() , которая отвечает за удаление записи, включает в себя следующие хуки:

  • before_delete_post;
  • delete_post;
  • deleted_post;
  • after_delete_post.
Префиксы имен хуков

Помимо позиции и значения нужно задать префикс хука префикса. Например:

  • wpseo_ от Yoast SEO;
  • genesis_ от фреймворка Genesis;
  • advanced_ads_ от моего плагина Advanced Ads.

Это предотвращает конфликты с хуками в других плагинах или темах оформления.

Динамические имена хуков

Предположим, что в плагине есть много параметров, и вы хотите, чтобы другие разработчики могли использовать фильтр для каждого из них. Для этого нужно вызывать apply_filters() для каждого параметра. Также можно использовать динамическое имя хука, как это делает ​​WordPress в функции get_options() .

Данная функция включает в себя следующие хуки:

  • ‘pre_option_’ . $option;
  • ‘default_option_’ . $option;
  • ‘option_’ . $option.

Зная это, вы сможете подключиться к option_blogname или option_blogdescription , чтобы динамически изменять название или описание блога.

Магический «all»

При вызове add_action() и add_filter() в качестве имени хука можно использовать специальный тег. Благодаря чему связанная функция будет использоваться для каждого хука.

Имена функций

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

add_filter("the_content","bestpluginever_capitalize_all_words");

Также возможно подключение статичной функции в классе:

add_filter("the_content",array("bestpluginever","capitalize_all_words"));

Ее вызов в экземпляре этого класса будет выглядеть следующим образом:

add_filter("the_content",array($bestpluginever,"capitalize_all_words"));

Также можно вызвать метод в экземпляре того же класса, например:

add_filter("the_content",array($this,"capitalize_all_words"));

Также убедитесь, что функции являются public .

Использование PHP функций по умолчанию

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

functionbestpluginever_capitalize_title($title){ returnucwords($title); } add_filter("the_title","bestpluginever_capitalize_title");

Поскольку ucwords() является стандартной функцией PHP, которая принимает и возвращает значение, ее можно сократить до одной строки:

add_filter("the_title","ucwords");

Приоритеты

Третий параметр в add_action() и add_filter() — это приоритет. Он устанавливает порядок, в котором вызываются функции, связанные с хуком.
Этот параметр является необязательным и по умолчанию равен 10, если не определен явно. Несколько функций с одинаковым приоритетом будут вызываться в том порядке, в котором они были зарегистрированы в хуке.
Плагин Advanced Ads использует the_content при вставке рекламных объявлений до или после контента. Ее третий параметр определяет, вставляется ли сначала рекламное объявление или другой контент. Чтобы избежать обращений за поддержкой относительно «неправильного» порядка элементов, я предоставил пользователям возможность выбирать приоритет фильтра в качестве опции.

Проверка выполнения действия

Чтобы проверить, выполнено ли конкретное действие, можно использовать did_action() .
Функция _wp_render_title_tag была подключена к wp_head . Это пример того, как ядро ​​Wordpress проверяет, что тег title действительно создан только тут.

function_wp_render_title_tag(){ if(!current_theme_supports("title-tag")){ return; } // Это может работать только внутри wp_head. if(!did_action("wp_head")&&!doing_action("wp_head")){ return; } echo"".wp_title("|",false,"right")."n"; }

did_action($hook) возвращает информацию о том, сколько раз было выполнено действие, включая текущий вызов. Функция вернет 1, если _wp_render_title_tag() запускается в wp_head . do_action(‘wp_head’) проверяет, находимся ли мы сейчас в действии wp_head . Фактически, приведенный выше код — это двойная проверка. Из-за этого он будет удален из WordPress 4.4.0.
Функция do_action() проверяет, действительно ли происходит действие.

Проверка использования фильтра

Для фильтров did_action() и do_action() нет псевдонимов. Вместо них нужно использовать has_filter($hook, $function) . Когда указан только $hook, будет возвращено значение true , если какая-либо функция зарегистрирована для hook. Значение false — в противном случае.
Если также передана функция $function , то будет возвращен приоритет этой функции, или значение false , если эта функция не подключена к хуку.
При добавлении рекламных объявлений после определенного абзаца плагин Advanced Ads должен убедиться, что wpautop() вызывается до того, как будет применена пользовательская функция фильтра.

$wpautop_priority=has_filter("the_content","wpautop"); if($wpautop_priority&&$advads_content_injection_priority() 1 ) :

  • echo "\n " ;
  • echo "
  • echo get_permalink( $post -> ID ) ;
  • echo "" />\n " ;
  • endif ;
  • add_action( "wp_head" , "canonical_for_comments" ) ;
  • Объяснение кода. Сначала, мы создаем функцию, которая добавляет к каждой странице с комментариями, кроме первой, тэг link с атрибутом rel=«canonical» . Затем, присоединяем эту функцию к Wordpress-функци wp_head() .8. ПОЛУЧЕНИЕ ПОСТА ИЛИ СТРАНИЦЫ В КАЧЕСТВЕ PHP-ПЕРЕМЕННОЙПроблема. Возможность получить текущий пост или целую страницу в качестве PHP переменной – действительно крутая вещь. Скажем, Вы можете заменять некоторые части контента при помощи функции str_replace() или делать с ним еще что-нибудь.Решение. И снова ничего сложного. Делаем все то же самое: вставляем следующий код в файл functions.php .
  • function callback($buffer ) {
  • // modify buffer here, and then return the updated code
  • return $buffer ;
  • function buffer_start() {
  • ob_start ("callback" ) ;
  • function buffer_end() {
  • ob_end_flush () ;
  • add_action("wp_head" , "buffer_start" ) ;
  • add_action("wp_footer" , "buffer_end" ) ;
  • Объяснение кода. Для того, чтобы этот хак работал, необходимы три функции:
    • callback() : эта функция возвращает страницу целиком как переменную $buffer . Вы можете модифицировать ее как угодно, например, при помощи регулярных выражений;
    • buffer_start() : эта функция начинает буферизацию. Ее мы присоединяем к функции wp_head() ;
    • buffer_end() : эта функция очищает буфер. Ее мы присоединяем к функции wp_footer() .
    9. ИСПОЛЬЗУЕМ ХУКИ И CRON ДЛЯ СОБЫТИЙ ПО РАСПИСАНИЮПроблема. Вы, наверное, уже знаете, что Wordpress может использовать события по расписанию. К примеру, можно публиковать посты в конкретное, установленное заранее, время. Используя хуки и wp-cron , мы можем запросто задать расписание для нашего собственного события. В следующем примере мы заставим блог отправлять нам сообщения на e-mail один раз каждый час.Решение. Вставляем следующий код в файл functions.php .
  • if (! wp_next_scheduled("my_task_hook" ) ) {
  • wp_schedule_event( time () , "hourly" , "my_task_hook" ) ;
  • add_action( "my_task_hook" , "my_task_function" ) ;
  • function my_task_function() {
  • wp_mail("[email protected]" , "Automatic email" , "Hello, this is an automatically scheduled email from WordPress." ) ;
  • Объяснение кода. Первое, что мы сделаем, конечно, - это создадим функцию, которая будет выполнять требуемое действие. В этом примере эта функция называется my_task_function() и она просто отправляет письмо на указанный e-mail адрес.
    Для того, чтобы запланировать выполнение этой функции, мы будем использовать функцию wp_schedule_event() . Последним аргументом, передаваемым ей, будет наш хук, поэтому мы «цепляем» нашу функцию my_task_function() к my_task_hook .10. СПИСОК ВСЕХ «ХУКНУТЫХ» ФУНКЦИЙПроблема. Когда что-то идет не так, здорово может пригодиться список всех «хукнутых» функций.Решение. Как и все предыдущие фрагменты кода следующий также необходимо вставить в файл functions.php . Только не забудьте удалить его после использования. Если Вы этого не сделаете, то сообщения будут появляться и после отладки.
  • function list_hooked_functions($tag = false ) {
  • global $wp_filter ;
  • if ($tag ) {
  • $hook [ $tag ] = $wp_filter [ $tag ] ;
  • if (! is_array ($hook [ $tag ] ) ) {
  • trigger_error ("Nothing found for "$tag " hook" , E_USER_WARNING ) ;
  • return ;
  • else {
  • $hook = $wp_filter ;
  • ksort ($hook ) ;
  • echo "" ;
  • foreach ($hook as $tag => $priority ) {
  • echo "
    >>>>>\t $tag
    " ;
  • ksort ($priority ) ;
  • foreach ($priority as $priority => $function ) {
  • echo $priority ;
  • foreach ($function as $name => $properties ) echo "\t $name
    " ;
  • echo "" ;
  • return ;
  • После того, как Вы вставите этот код в файл functions.php , вызовите функцию list_hooked_functions() . Она и покажет Вам список всех «хукнутых» функций.

    Объяснение кода. Данный код выясняет, передается ли имя хука в качестве аргумента функции. Если передается, то на экран выводится имя хука. Также можно посмотреть хуки только для определенной функции:

    Срабатывает перед подключением подобранного файла шаблона темы, например: single.php , page.php , search.php , 404.php и т.д. Этот фильтр используется для изменения пути до такого файла.

    Фильтр срабатывает после события template_redirect и после того, как WordPress подберет файл, который будет использоваться в качестве файла шаблона. Для каждого типа страницы, файл разный: см. Иерархию файлов темы . Например, мы зашли на постоянную страницу, WordPress подбирает какой файл шаблона должен быть показан - это файл page.php: home/site.ru/wp-content/themes/mytheme/page.php . С помощью этого фильтра можно изменить путь такого файла.

    Во время этого фильтра уже можно использовать условные теги и переменная $post уже определена.

    Использование add_filter("template_include", "filter_function_name_11"); function filter_function_name_11($template) { // Фильтр... return $template; } $template(строка) Полный путь до файла, который будет подключен в качестве шаблона. Пр: home/wptest.ru/wp-content/themes/publisher/page.php . Примеры #1 Файл в каталоге темы

    Шаблон постоянной странице можно задать создав файл в каталоге темы и в начале файла указать PHP комментарий:

    Заголовок

    Какой-то текст