Используйте всю мощь хуков WordPress: объяснение действий и фильтров

Опубликовано: 2022-07-22

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

Хуки WordPress: действия и фильтры

Крючки WordPress — это не просто мощные инструменты настройки, это то, как компоненты WordPress взаимодействуют друг с другом. Подключенные функции управляют многими рутинными задачами, которые мы считаем неотъемлемой частью WordPress, такими как добавление стилей или скриптов на страницу или окружение текста нижнего колонтитула элементами HTML. Поиск в кодовой базе WordPress Core выявляет тысячи хуков в более чем 700 местах. Темы и плагины WordPress содержат еще больше хуков.

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

Инфраструктура WordPress

Модульные элементы WordPress легко интегрируются друг с другом, поэтому мы можем легко смешивать, сопоставлять и комбинировать:

  1. Ядро WordPress: это файлы, необходимые для работы WordPress. WordPress Core предоставляет обобщенную архитектуру, панель администратора WP, запросы к базе данных, безопасность и многое другое. Ядро WordPress написано на PHP и использует базу данных MySQL.
  2. Тема (или родительская тема): Тема определяет основной макет и дизайн веб-сайта. Работающая на основе файлов PHP, HTML, JavaScript и CSS, тема функционирует, читая базу данных WordPress MySQL для создания HTML-кода, который отображается в браузере. Хуки в теме могут, например, добавлять таблицы стилей, сценарии, шрифты или пользовательские типы сообщений.
  3. Дочерняя тема: мы сами создаем дочерние темы, чтобы точно настроить базовый макет и дизайн, предоставляемые родительскими темами. Дочерние темы могут определять таблицы стилей и сценарии для изменения унаследованных функций или добавления или удаления типов записей. Инструкции дочерней темы всегда замещают инструкции родительской темы.
  4. Плагин(ы): Чтобы расширить внутреннюю функциональность WordPress, мы можем выбирать из тысяч сторонних плагинов. Хуки в плагине могут, например, уведомлять нас по электронной почте о публикации сообщения или скрывать отправленные пользователями комментарии, содержащие запрещенную лексику.
  5. Пользовательские плагины: если сторонний плагин не полностью соответствует потребностям бизнеса, мы можем ускорить его, написав пользовательский плагин на PHP. Или мы можем написать новый плагин с нуля. В обоих случаях мы бы добавили хуки для расширения существующей функциональности.

Пирамида, показывающая пять уровней от основания к вершине: (1) ядро ​​WordPress, (2) тема, (3) дочерняя тема, (4) плагины, (5) пользовательские плагины.
Иерархия инфраструктуры WordPress

Учитывая, что у нас есть доступ к исходникам всех пяти слоев, зачем нужны хуки в WordPress?

Код безопасности

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

Если мы напрямую изменяем локальные копии вышестоящих компонентов WordPress, мы сталкиваемся с проблемой: обновления перезаписывают наши настройки. Как мы можем обойти это при настройке WordPress? С помощью хуков, в дочерней теме и пользовательских плагинах.

Кодирование в нашей дочерней теме

Дочерняя тема — это безопасное пространство, где мы можем настроить внешний вид нашей установленной темы. Любой код, добавленный сюда, переопределит аналогичный код в родительском объекте без риска быть перезаписанным обновлением.

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

Написание пользовательских плагинов

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

Где разместить наши хуки в WordPress

Цель Пример Где?
Дочерняя тема PHP Пользовательский плагин PHP
Чтобы изменить структуру веб-страницы Добавление пользовательской таблицы стилей для изменения цветов и шрифтов элементов веб-сайта
Чтобы изменить функциональность другого плагина (например, создать плагин для улучшения функциональности стороннего плагина) Добавление подзаголовка (например, «Новости») к пользовательским типам сообщений
Чтобы добавить новую функцию, выходящую за рамки WordPress Core Изменение рабочего процесса, который происходит при посещении поста, чтобы включить обновление счетчика в базе данных.

Подготовка к погружению: определения

Чтобы избежать смешения терминов, мы будем придерживаться этой терминологии:

  • Хук — это приятное место в WordPress, где функции регистрируются для запуска. Мы можем подключить наши функции к одному из множества хуков в WordPress и его компонентах или создать свои собственные.
    • Хук действия запускает действия.
    • Хук фильтра запускает фильтры.
  • Подключенная функция — это пользовательская функция обратного вызова PHP, которую мы «прицепили» к месту перехвата WordPress. Какой тип использовать, зависит от того, предназначен ли хук для разрешения изменений вне функции — например, добавление непосредственно к выходным данным веб-страницы, изменение базы данных или отправка электронной почты. Они известны как побочные эффекты .
    • Фильтр (или функция фильтра ) должен избегать побочных эффектов, работая только с переданными ему данными, а затем возвращая измененную копию.
    • Действие (или функция действия ), напротив, должно вызывать побочные эффекты. Он не имеет возвращаемого значения.

Диаграмма, показывающая функции в паре с совместимыми хуками. К хукам-фильтрам прикреплены функции фильтрации, а к хукам-действиям прикреплены функции-действия.
Хуки WordPress могут иметь несколько функций обратного вызова, но все функции обратного вызова должны соответствовать типу хука, в котором они зарегистрированы.

Имея в виду эти различия, мы можем начать изучение хуков.

Абстракция и чистый код

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

Продуманная номенклатура

Заблаговременно избегайте конфликтов, давая уникальное имя дочерней теме или настраиваемым плагинам. Наличие хуков с одинаковыми именами на одном сайте — это рецепт непреднамеренного поведения кода. Передовая практика предписывает начинать имя нашего хука с уникального короткого префикса (например, инициалы автора, проекта или компании), за которым следует описательное имя хука. Например, используя шаблон «инициалы проекта плюс имя хука» для проекта Tahir's Fabulous Plugin, мы могли бы назвать наши хуки tfp-upload-document или tfp-create-post-news .

Параллельная разработка и отладка

Один хук может запускать более одного действия или фильтра. Например, мы могли бы написать веб-страницу, содержащую несколько сценариев, каждый из которых использует хук действия wp_head для печати HTML (например, раздела <style> или <script> ) в разделе <head> на внешнем интерфейсе страницы.

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

Действия

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

  • Создание данных.
  • Чтение данных.
  • Изменение данных.
  • Удаление данных.
  • Запись разрешений вошедших в систему пользователей.
  • Отслеживание местоположений и сохранение их в базе данных.

Примеры событий, при которых могут быть инициированы действия, включают:

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

Действие может взаимодействовать с API для передачи данных (например, ссылки на публикацию в социальных сетях), но оно не будет возвращать данные вызывающему хуку.

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

Нет коротких путей к поиску нашего крючка: мы учились бы на опыте или тщательно изучали перечисленные действия, чтобы найти вероятных кандидатов. Мы могли бы рассмотреть save_post как кандидата, но быстро исключили бы его, поскольку он срабатывал бы несколько раз в течение одного сеанса редактирования. Лучший выбор — transition_post_status , который срабатывает только при изменении статуса сообщения (например, с draft на publish , с publish на trash ).

Мы пойдем с transition_post_status , но также уточним наше действие, чтобы оно запускалось только тогда, когда статус нашего сообщения переходит на publish . Кроме того, следуя официальной документации и API-интерфейсам различных платформ социальных сетей, мы можем интегрировать и публиковать содержимое нашего сообщения вместе с избранным изображением:

 <?php function publish_post_on_social_media ( $new_status = NULL, $old_status = NULL, $post_ID = NULL ) { if ( 'publish' == $new_status && 'publish' != $old_status ) { // build the logic to share on social media } } add_action( 'transition_post_status', 'publish_post_on_social_media', 10, 3 ); ?>

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

Назначение приоритетов с помощью wp_enqueue_scripts

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

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

  1. Родительская тема
  2. Детская тема
  3. Любые плагины

В этой конструкции:

 add_action( string $hook_name, callable $callback, int $priority = 10, int $accepted_args = 1)

…значение priority добавленного действия определяет порядок его выполнения:

  • Значение priority по умолчанию для wp_enqueue_scripts (или любого действия) — «10».
  • Функция запускается раньше, если мы сбрасываем ее priority на более низкое значение.
  • Функция запускается позже, если мы сбрасываем ее priority на более высокое значение.

Чтобы загрузить таблицу стилей нашей дочерней темы последней, используйте wp_enqueue_scripts , действие, которое обычно используется темами и плагинами WordPress. Нам нужно только изменить приоритет действия wp_enqueue_scripts нашей дочерней темы на число, превышающее значение по умолчанию «10», скажем, «99»:

 add_action( 'wp_enqueue_scripts', 'child_theme_styles', 99 );



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

Фильтры

Фильтр позволяет нам изменять данные до того, как они будут обработаны для отображения в браузере. С этой целью фильтр принимает переменную (переменные), изменяет переданное значение (значения) и возвращает данные для дальнейшей обработки.

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

Один из моих клиентов персонализирует продукты, которые он продает, печатая на них изображения, предоставленные покупателями. Этот клиент использует плагин WooCommerce для управления электронной коммерцией. WooCommerce не поддерживает эту функцию «из коробки». Поэтому я добавил два фрагмента кода в functions.php моего клиента:

  1. woocommerce_checkout_cart_item_quantity , указанный в документации WooCommerce, представляет собой хук-фильтр, который позволяет покупателям добавлять внешние элементы в свои корзины перед оформлением заказа.
  2. my_customer_image_data_in_cart — это фильтр, который мы напишем сами и будем использовать для запуска woocommerce_checkout_cart_item_quantity всякий раз, когда WooCommerce подготавливает корзину для отображения.

Используя следующий шаблон, мы можем добавить наш фильтр и изменить поведение корзины по умолчанию:

 add_filter( 'woocommerce_checkout_cart_item_quantity', 'my_customer_image_data_in_cart', 1, 3 ); function my_customer_image_data_in_cart( $html, $cart_item, $cart_item_key ) { if ( !empty( $cart_item['images_data'] ) ) { // Store image // Get image URL // Modify $html } return $html; }

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

Индивидуальные обработчики действий и обработчики фильтров

Написание настраиваемых хуков действий не расширяет ядро ​​Wordpress, а просто создает новые триггерные точки в нашем собственном коде.

Создание пользовательских хуков действий

Добавление пользовательского хука в нашу тему или плагин позволяет другим разработчикам расширять функциональность без изменения нашей кодовой базы. Чтобы добавить пользовательский хук, используйте ту же технику, которую использует сама база кода WordPress Core: в желаемой точке срабатывания мы просто вызываем do_action с именем нашего нового хука, при желании добавляя столько аргументов, сколько наши обратные вызовы могут счесть полезными:

 do_action( 'myorg_hello_action', $arg1, $arg2 );

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

Теперь, когда мы определили myorg_hello_action , разработчики могут подключиться точно так же, как мы рассмотрели ранее для встроенных ловушек: определить функцию, затем вызвать add_action() .

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

Создание пользовательских хуков фильтров

Паттерн WordPress для настраиваемых хуков фильтров такой же, как и для хуков действий, за исключением того, что мы вызываем apply_filters() вместо do_action() .

На этот раз рассмотрим более конкретный пример. Предположим, наш плагин создает боковое меню, которое обычно состоит из четырех пунктов. Мы добавим настраиваемый хук-фильтр, чтобы мы (и последующие разработчики) могли изменять этот список элементов в другом месте:

 // Text labels of sidebar menu $sidebar_menu = array( "Page One", "Page Two", "Page Three", "Page Four" ); $sidebar_menu = apply_filters( 'myorg_sidebar_menu', $sidebar_menu );

Вот и все — наш пользовательский хук-фильтр myorg_sidebar_menu теперь готов к использованию в плагине, который может быть загружен позже или где-то еще в этом плагине. Это позволяет любому, кто пишет нисходящий код, настраивать нашу боковую панель.

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

 function lowercase_sidebar_menu( $menu ) { $menu = array_map( 'strtolower', $menu ); return $menu; } function add_donate_item( $menu ) { $menu = array_push( $menu, 'Donate' ); return $menu; }

Как и в наших предыдущих примерах, теперь мы готовы подключить наши функции обратного вызова фильтра к нашему пользовательскому хуку:

 add_filter( 'myorg_sidebar_menu', 'add_donate_item', 100 ); add_filter( 'myorg_sidebar_menu', 'lowercase_sidebar_menu' );

Таким образом, мы подключили наши два примера функций обратного вызова к нашему пользовательскому фильтрующему хуку. Оба теперь изменяют исходное содержимое $the_sidebar_menu . Поскольку мы присвоили add_donate_item более высокий priority , он запускается позже, после выполнения lowercase_sidebar_menu .

Три панели, отображающие результаты функций фильтра, описанных в этом разделе. Панель 1 показывает боковую панель в том виде, в каком она была бы, если бы к фильтру не был подключен обратный вызов. Панель 2 показывает боковую панель в том виде, в каком она была бы, если бы обратный вызов lowercase_sidebar_menu был подключен к фильтру, со всеми четырьмя именами элементов в нижнем регистре. Панель 3 показывает боковую панель в том виде, в котором она была бы, если бы обратный вызов donate_button также был подключен к фильтру — те же строчные буквы, что и на панели 2, плюс пятый элемент «Пожертвовать», оставленный в заголовке.

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

Нет предела возможностям с действиями и фильтрами

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

Блог Toptal Engineering выражает благодарность Фахаду Муртазе за его опыт, бета-тестирование и технический обзор этой статьи.