Что такое WordPress хуки и как их использовать? Инициализационные хуки WordPress: преимущества и типичные ошибки

Что такое хуки? Простыми словами хуки это функции wordpress, к которым можно привязать свои функции. В переводе с английского hook это крюк, таким образом вы как бы привязываетесь к стандартной функции. Например, на функцию удаления записи, привязываем свою функцию, которая будет срабатывать только при удалении поста. С помощью грамотного использования хуков, можно значительно расширить базовый функционал WordPress.

Я на маленьком примере покажу, как можно использовать хуки WordPress. За основу возьмем хук публикации поста publish_post, и создадим для него функцию, которая будет добавлять пользователю балы за добавление постов.

Как использовать хук

Хуки используются либо в плагинах, или в functions.php. Чтобы вызвать хук нужно прописать:

Add_action("publish_post", "add_point");

add_point – Название функции, которую вы создаете.

Пример функции с хуком

В моем случае функция работает таким образом:

Пользователь добавляет запись, срабатывает хук который вызывает функцию, в которой происходит вся магия 🙂 В функции я работаю с классом $wpdb->update , где обновляю таблицу с балами конкретного пользователя. В уроке , я рассказывал о классе $wpdb->insert на основе которого вы можете сделать свою функцию с использованием $wpdb->update, данный класс работает аналогичным образом.

Вот как примерно выглядит конструкция с использованием хука:

Function add_point() { //Тут функция } add_action("publish_post", "add_point");

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

Вот функция с обновлением баллов:

Function add_point() { global $wpdb; $user_ID = get_current_user_id(); $result = $wpdb->get_results("SELECT points FROM user_points WHERE user = "".$user_ID."""); $update = $result->points + 10; $wpdb->update("user_points", array("points" => $update,), array("user" => $user_ID), array("%d",), array("%d")); } add_action("publish_post", "add_point");

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

Хуки являются очень полезными фишками в Wordpress. Они позволяют как бы «посадить» пользовательскую функцию «на крючок» функции существующей, разрешая тем самым изменять функциональность Wordpress без внесения изменений в файлы ядра движка. В этой статье мы представляем Вам 10 особенно полезных, готовых к использованию хуков для Wordpress, с примерами и пояснениями их исходников.ЧТО ТАКОЕ ХУК? Для достижения определенного эффекта нам нужно слегка изменить принцип работы Wordpress. Некоторые модификации необходимо внести в файлы, которые были названы разработчиками файлами ядра – они нужны для того, чтобы Wordpress работал должным образом.
Но изменение файлов ядра – плохая идея: это может создать брешь в системе безопасности блога. Также, все модификации исчезнут, как только Вы обновите движок до новой версии.
Однако, расширение функциональности все же необходимо. Для этого разработчиками был придуман Plugin API.
Хуки являются одним из главных блоков для построения плагинов. Почти каждый подключаемый плагин использует хуки для расширения функциональности Wordpress.КАК ИСПОЛЬЗОВАТЬ ХУКИ В ВАШЕМ БЛОГЕ Пока Вы не написали свой плагин, Вы должны записать хуки в файл functions.php . Этот файл находится в директории wp-content/themes/yourtheme (где /yourtheme – директория, в которой находится текущая тема).
Вот пример, который показывает, как подключить Вашу пользовательскую функцию к функции ядра движка:
  • add_action ( "publish_post" , "myCustomFunction" ) ;
  • В этом примере мы подключили пользовательскую функцию myCustomFunction() к функции ядра publish_post() . Функция myCustomFunction() будет выполняться при каждом выполнении функции publish_post() .
    Конечно, мы можем также удалить хук, используя функцию remove_action() :

  • remove_action ( "publish_post" , "myCustomFunction" ) ;
  • 1. ОТКЛЮЧАЕМ АВТОМАТИЧСКОЕ ФОРМАТИРОВАНИЕ В WORDPRESSПроблема. Вы, наверное, уже замечали, что типограф Wordpress по умолчанию превращает «прямые» кавычки в «кривые» и делает другие мелкие изменения в форматировании поста.
    Это хорошо, если блоггер размещает обычный контент (подразумеваются обычный текст и картинки). Но некоторые постят исходный код, чтобы потом его обсуждать, и они будут очень недовольны, когда из-за этих «кривых» кавычек интерпретатор иди компилятор выдадут им сообщения о синтаксических ошибках.Решение. Просто вставьте в файл functions.php нижеследующий код:
  • function my_formatter($content ) {
  • $new_content = "" ;
  • $pattern_full = "{(\.*?\)}is" ;
  • $pattern_contents = "{\(.*?)\}is" ;
  • $pieces = preg_split ($pattern_full , $content , - 1 , PREG_SPLIT_DELIM_CAPTURE) ;
  • foreach ($pieces as $piece ) {
  • if (preg_match ($pattern_contents , $piece , $matches ) ) {
  • $new_content .= $matches [ 1 ] ;
  • } else {
  • $new_content .= wptexturize(wpautop($piece ) ) ;
  • return $new_content ;
  • remove_filter("the_content" , "wpautop" ) ;
  • remove_filter("the_content" , "wptexturize" ) ;
  • add_filter("the_content" , "my_formatter" , 99 ) ;
  • После того, как Вы это сделали, можете использовать тэг для того, чтобы текст поста был не отформатирован автоматически:

    This text will not be automatically formatted.Объяснение кода. Первым делом, мы создаем функцию, которая, основываясь на регулярных выражениях, находит тэг в содержании Вашего поста.
    Далее, мы привязываем нашу функцию my_formatter() к функции the_content() , что означает выполнение нашей функции всякий раз, когда вызывается функция the_content() .
    Для того, чтобы отключить автоформатирование, мы использовали функцию remove_filter() .2. ОПРЕДЕЛЯЕМ БРАУЗЕР ПОСЕТИТЕЛЯ ПРИ ПОМОЩИ ХУКОВПроблема. Кросс-браузерная совместимость – это наиболее распространенная проблема в web-разработке. Вы сэкономите много нервов и времени, если сможете определить браузер пользователя, зашедшего на Ваш блог, а затем создав CSS-класс для тэга body под каждый из браузеров. Решение. Ничего сложного: просто вставьте нижеследующий код в файл functions.php , сохраните его – все готово!
  • add_filter("body_class" , "browser_body_class" ) ;
  • function browser_body_class($classes ) {
  • global $is_lynx , $is_gecko , $is_IE , $is_opera , $is_NS4 , $is_safari , $is_chrome , $is_iphone ;
  • if ($is_lynx ) $classes = "lynx" ;
  • elseif ($is_gecko ) $classes = "gecko" ;
  • elseif ($is_opera ) $classes = "opera" ;
  • elseif ($is_NS4 ) $classes = "ns4" ;
  • elseif ($is_safari ) $classes = "safari" ;
  • elseif ($is_chrome ) $classes = "chrome" ;
  • elseif ($is_IE ) $classes = "ie" ;
  • else $classes = "unknown" ;
  • if ($is_iphone ) $classes = "iphone" ;
  • return $classes ;
  • После того, как Вы сохраните файл, функция автоматически будет добавлять CSS-класс, соответствующий пользовательскому браузеру, для тэга body :

    Объяснение кода. Wordpress имеет глобальные переменные, которые возвращают true , если пользователь использует соответствующий браузер. Если пользователь использует браузер Google Chrome, то переменная $is_chrome примет значение true . Вот для чего мы и создаем функцию browser_body_class() . После этого мы присоединяем ее к Wordpress функции body_class() .3. ОПРЕДЕЛЕНИЕ ТЕКСТА ПО УМОЛЧАНИЮ В РЕДАКТОРЕ TinyMCEПроблема. Многие блоггеры почти всегда используют для своего блога один и тот же формат. Сообщения в моем блоге WpRecipes.com всегда отображаются одинаково: текст, код, еще немного текста.
    Можно сэкономить немало времени, если научить TinyMCE отображать какой-нибудь текст по умолчанию.Решение. Как всегда, решением является хук. Копируем код в файл functions.php и смотрим, как он работает.
  • add_filter("default_content" , "my_editor_content" ) ;
  • function my_editor_content( $content ) {
  • $content = "If you enjoyed this post, make sure to subscribe to my rss feed." ;
  • return $content ;
  • Объяснение кода. Этот код хоть и простой, но очень мощный. Просто создаем функцию, которая возвращает требуемый текст (в этом примере мы определяем текст, который спрашивает у посетителей о подписке на RSS-ленту), и присоединяем ее к Wordpress-функции default_content() . Вот так.4. ВСТАВЛЯЕМ КОНТЕНТ АВТОМАТИЧЕСКИ ПОСЛЕ КАЖДОГО ПОСТАПроблема. В большинстве блогов для вывода контента после каждого поста файл single.php , но вот беда: этот контент не будет отображаться в RSS-ленте. Хуки помогут исправить эту проблему.Решение. Все то же самое – просто копируем следующий код в файл fucntions.php .
  • function insertFootNote($content ) {
  • $content .= "" ;
  • $content .= "Enjoyed this article?" ;
  • $content .= "

    Subscribe to our RSS feed and never miss a recipe!

    " ;
  • $content .= "" ;
  • return $content ;
  • add_filter ("the_content" , "insertFootNote" ) ;
  • Объяснение кода. Суть функции insertFootNote() проста: он лишь конкатенирует желаемый текст к переменной $content , в которой хранится содержание поста.
    Затем, мы присоединяем нашу функцию insertFootNote() к функции the_content() .
    Видите в строке 2 вот такой код:
  • if (! is_feed() && ! is_home() ) {
  • Если Вам нужно, чтобы текст попадал в RSS-ленту, то замените предыдущий код на этот:

  • if (! is_home() ) {
  • Вот и все.

    5. ОТКЛЮЧАЕМ СООБЩЕНИЕ С ПРОСЬБОЙ ОБНОВИТЬСЯ В ПАНЕЛИ УПРАВЛЕНИЯ WORDPRESSПроблема. Вы можете видеть информацию о наличии новой версии Wordpress вверху дашборда. Это действительно хорошая штука, так как обновление закрывает дыры в безопасности и позволяет пользоваться Вам последними возможностями движка. Но если блог не Ваш лично, а является проектом для кого-нибудь из клиентов, то давать возможность клиентам самим обновляться – не есть хорошая идея.Решение. Просто вставьте следующий код в файл fucntions.php .
  • if (! current_user_can("edit_users" ) ) {
  • add_action( "init" , create_function ( "$a" , "remove_action("init", "wp_version_check");" ) , 2 ) ;
  • add_filter( "pre_option_update_core" , create_function ( "$a" , "return null;" ) ) ;
  • После того, как Вы сохраните файл functions.php , сообщения Вы больше не увидите.

    Объяснение кода. Для начала, убедимся, что текущий пользователь обладает достаточными правами администратора, чтобы можно было обновить Wordpress. Как только мы в этом убедились, создаем пару хуков, которые переписывают правила отображения сообщений в дашборде.6. ОТКЛЮЧАЕМ АВТОСОХРАНЕНИЕ ПОСТОВПроблема. Wordpress периодически сохраняет пост по мере его введения. Это полезная возможность, но иногда она не требуется.Решение. Для того, чтобы отключить автосохранение поста, просто откройте файл functions.php и вставьте в него следующий код.
  • function disableAutoSave() {
  • wp_deregister_script("autosave" ) ;
  • add_action( "wp_print_scripts" , "disableAutoSave" ) ;
  • Объяснение кода. И вновь, ничего сложного: мы просто создаем функцию, которая отключается автосохранение и привязываем ее к Wordpress-функции wp_print_scripts() .7. ИЗБАВЛЯЕМСЯ ОТ ПОВТОРЯЮЩЕГОСЯ КОНТЕНТА НА СТРАНИЦАХ С КОММЕНТАРИЯМИПроблема. Повторяющийся контент эта довольно распространенная SEO-проблема.
    Введенная в Wordpress версии 2.7 система разбиения комментариев на страницы эту проблему не решает.
    Для предупреждения повторяющегося контента в комментариях будем использовать атрибут rel=«canonical» .Решение. Копируем следующий код и вставляем его в файл functions.php .
  • function canonical_for_comments() {
  • global $cpage , $post ;
  • if ( $cpage > 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() . Она и покажет Вам список всех «хукнутых» функций.

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

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

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

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

    Введение в инициализационные хуки

    WordPress предоставляет большой набор хуков для использования в разработке плагинов и тем. В стандартном запросе все хуки действий выполняются в определенной последовательности. А именно, все они исполняются после того, как ядро WordPress завершает процесс загрузки.

    Так, инициализационные хуки используются в основном, как вы уже догадались, для инициализации процесса в темах и плагинах. Давайте посмотрим на доступные хуки init в порядке их исполнения:

    • init выполняется после того, как WordPress закончила загрузку, но до отправки заголовков.
    • widgets_init применяется для регистрации боковых виджетов приложения. Функция register_widget выполняется внутри этого хука.
    • admin_init выполняется в первую очередь, когда пользователь заходит в администраторскую часть WordPress. Обычно он используется для инициализации настроек, специфичных для админки.

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

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

    Определение admin_ init внутри хука init

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

    add_action("init", "test_init"); function test_init(){ add_action("admin_init", "test_admin_init"); } function test_admin_init() { echo "Admin Init Inside Init"; }

    function test_init () {

    echo "Admin Init Inside Init" ;

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

    Определение внутри init хука admin_ init

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

    add_action("admin_init", "test_admin_init"); function test_admin_init() { add_action("init", "test_init"); } function test_init() { echo "Init Inside Admin Init"; }

    add_action ("admin_init" , "test_admin_init" ) ;

    function test_admin_init () {

    add_action ("init" , "test_init" ) ;

    function test_init () {

    echo "Init Inside Admin Init" ;

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

    Исследование хуков init и admin_ init

    Среди множества хуков инициализации, init и admin_init стоят изучения, так как именно они широко используются во многих плагинах. Поэтому использование других хуков инициализации всегда сравнивается непосредственно с этими двумя.

    Сейчас мы рассмотрим функциональность init и admin_init хуков.

    init исполняется в каждом запросе как для фронт-энда, так и для администраторской части WordPress сайта. admin_init выполняется после того, как администраторская часть завершает процесс загрузки. Соответственно, он тоже выполняется в каждом запросе на чтение страницы в админской части сайта. Чтобы воспользоваться его преимуществами, пользователи должны быть авторизованы.

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

    Как правильно использовать init хуки

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

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

    init хук

    • Регистрация пользовательских типов записей – WordPress рекомендует использовать initхук для регистрации новых пользовательских типов контента.
    • Инициализация конфигурации и настроек вашего плагина – конфигурации и настройки плагина должны быть определены в каждом запросе и, следовательно, наилучшим подходом к этому будет включить их в хук init.
    • Доступ к данным, отправленным пользователем (Используя $_GET и $_POST) – Мы можем без каких-либо действий перехватить данные, отправленные пользователем, но рекомендуется использовать init хук, так как при этом гарантируется выполнение действия в каждом запросе.
    • Добавление новых правил перезаписи – Можно определить новые правила перезаписи, используя хук init, но помните, что новые правила возымеют эффект только после обновления всех правил перезаписи.
    • Добавление или удаление пользовательских действий – Плагины содержат множество пользовательских действий, позволяющих расширить функциональность. Могут быть такие сценарии, где нам потребуется добавить новые пользовательские действия, равно как удалить существующие. В этих случаях, необходимо выполнять эти действия внутри init хука.
    • Указание пути к языковым файлам плагина — WordPress предлагает многоязыковую поддержку, и поэтому мы можем загрузить файл, в котором содержатся переведенные строки. Это также можно разместить внутри init хука.

    Хук admin_ init.

    • Получение контроля – Необходимо проверить разрешения авторизованных пользователей до того, как дать каждому из них доступ к определенному набору фич или функционалу. admin_init– это первое, что выполняется в админской части, а значит, мы можем использовать его для управления доступом.
    • Добавление новых настроек – Мы можем применить этот хук для добавления новых установочных страниц или настроек на существующую панель настроек WordPress.

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

    Типичные ошибки при использовании хуков инициализации

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

    Давайте определим основные ошибки и найдем, как их избежать:

    • Обновление правил перезаписи – Это ресурсоемкая операция, которая обновляет и сортирует все правила перезаписи для добавления новых и удаления ненужных правил. Многие разработчики предпочитают обновлять правила перезаписи внутри действий init и заканчивают тем, что создают избыточную нагрузку в каждом запросе. Чтобы избежать этого, мы должны придумать, как провести обновление правил перезаписи вручную, используя кнопку, или обновлять их внутри таких нерегулярных действий, как сохранение настроек плагина.
    • Доступ к базе данных – Предоставление различной функциональности требует доступа к базе данных, но важно убрать лишние запросы к БД внутри хуков инициализации, так как в противном случае они будут выполняться в каждом запросе. В данном случае, идеальным решением будет встроить хуки с запросами к БД в функционально-специфичные хуки, чтобы избежать чрезмерной нагрузки.
    • Выполнение процедур обновления до новых версий – Чтобы иметь возможность обновить функционал плагинов до новых версий, в них должна быть продумана процедура апгрейда. Обычно разработчики применяют init хуки, чтобы проверить версии плагинов и настроек перед тем, как запустить процесс апгрейда. Мы можем позволить пользователям обновить плагин, предоставив им пользовательское окно, вместо автоматической проверки в каждом запросе.
    • Выполнение хуков инициализации вместо функционально-специфичных хуков – Это одна из самых типичных ошибок, допускаемых разработчиками. Существует множество хуков в WordPress, которые созданы для разных, уникальных целей. Важно использовать их, чтобы избежать возможных конфликтов и сделать код расширяемым. Такие хуки как admin_init и init, в принципе, могут использоваться вместо специальных, поэтому разработчики склонны применять их, не задумываясь о последствиях. Некоторые из типичных сценариев, где разработчики используют init и admin_init хуки вместо рекомендуемых:
    • admin _ menu – Можно добавлять страницы меню, используя функцию add_menu_page. Рекомендуется использовать admin_menu хук для создания страниц админки. Однако многие разработчики предпочитают применять admin_init, так как он исполняется после admin_menu хука.
    • wp _ enqueue _ scripts – Наиболее удачный способ добавления скриптов и стилей– это использовать wp_enqueue_scripts хук. Но многие применяют для загрузки скриптов и стилей wp_enqueue_script внутри init.

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

    Хуки инициализации: двигаемся дальше

    Хуки инициализации 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() Заголовок

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

    Понравилась статья? Поделиться с друзьями: