Плагины и темы WordPress меняют то, что отображается на экране, и то, как обрабатываются данные, без необходимости изменять файлы самого ядра WordPress (код в каталогах wp-includes / wp-admin ). Сделать это позволяет механизм под названием хуки (hooks), которые делятся на два типа: экшены (actions) и фильтры (filters). Тема этого блога, wpmm-blog , активно использует оба типа в своем файле functions.php , поэтому в этой статье мы разберем реальные примеры кода из нее.
Примечание: хук — это точка, которую разработчики ядра WordPress намеренно заложили для подключения стороннего кода. В определенных местах исходного кода ядра уже встроены вызовы вроде
do_action()иapply_filters(). Плагины и темы «цепляют» (hook) свои функции к этим точкам, чтобы перехватывать выполнение в нужный момент, не изменяя файлы ядра.
Чем экшен отличается от фильтра
Разница между этими двумя типами хуков предельно проста: возвращают ли они значение.
- Экшен (Action): выполняет определенный код в заданный момент. Ему ничего не нужно возвращать — он предназначен для побочных эффектов (запись лога, сохранение данных, отправка внешнего запроса).
- Фильтр (Filter): получает значение, которое уже есть у ядра, изменяет его и возвращает обратно. Он нужен для модификации данных прямо перед тем, как ядро их использует или выводит.
Кратко говоря: экшен прерывает процесс, чтобы выполнить некое действие; фильтр перезаписывает значение и возвращает его. Как только вы поймете, что именно требуется вашему коду, выбор между регистрацией через add_action() или add_filter() станет очевидным.
Пример фильтра: длина анонса и маркер «читать далее»
По умолчанию ядро WordPress обрезает анонсы (excerpt) на страницах архивов до 55 слов, добавляя в конце […] . Чтобы изменить это поведение, не нужно лезть в исходный код ядра — достаточно зарегистрировать функции на два хука-фильтра: excerpt_length и excerpt_more .
if (!function_exists('wpmm_blog_excerpt_length')) {
function wpmm_blog_excerpt_length($length) {
// Japanese content is measured in "words" here too, but 60
// reads as a reasonable length even with full-width characters
return 60;
}
}
add_filter('excerpt_length', 'wpmm_blog_excerpt_length');
if (!function_exists('wpmm_blog_excerpt_more')) {
function wpmm_blog_excerpt_more($more) {
return ' …';
}
}
add_filter('excerpt_more', 'wpmm_blog_excerpt_more');
Ключевая деталь: каждая функция получает стандартное значение от ядра в качестве аргумента и возвращает замену. Функция wpmm_blog_excerpt_length($length) принимает дефолтное значение ядра (55) как $length , но эта реализация игнорирует его и всегда возвращает фиксированное число 60. Внутренняя логика ядра берет то, что вернула функция, и использует это значение в качестве новой длины анонса.
Пример экшена: предварительная генерация OGP-изображения при сохранении
В качестве примера экшена: этот блог предварительно генерирует и кэширует OGP-изображение (Open Graph) записи в момент ее сохранения или публикации, используя хук save_post .
add_action('save_post', '_wpmm_blog_pregenerate_ogp_on_publish', 10, 3);
Функция add_action() принимает по порядку: имя хука, функцию обратного вызова (callback), приоритет и количество аргументов, которые ожидает callback. В данном вызове используется приоритет 10 (по умолчанию) и запрашивается 3 аргумента.
Событие save_post способно передавать своим callback-функциям три аргумента — $post_ID , $post (объект записи) и $update (булево значение, указывающее, обновление это или новая запись), — но эта возможность доступна только в том случае, если callback явно запрашивает такое количество аргументов; по умолчанию передается только первый. Параметр 3 в конце этого вызова существует специально для того, чтобы callback мог использовать все три аргумента.
Зачем нужен приоритет
У такого популярного хука, как save_post , часто бывает сразу несколько плагинов или тем, регистрирующих свои callback-функции одновременно, не говоря уже о собственном встроенном использовании этого хука ядром. Когда у всех callback-функций установлен одинаковый приоритет по умолчанию (10), они выполняются в порядке регистрации. Однако на практике иногда требуется «выполнить после вот этого callback» или «выполнить раньше всего остального», и приоритет служит как раз явным числовым регулятором для этого. Меньшие числа выполняются раньше, большие — позже.
Почему благодаря этому ядро никогда не приходится редактировать напрямую
В исходном код ядра WordPress в ключевых точках по всему проекту встроены вызовы do_action('hook-name', ...) (вызов экшена) и apply_filters('hook-name', $value, ...) (применение фильтра). Плагины и темы регистрируют свои callback-функции для этих заранее подготовленных точек входа с помощью add_action() / add_filter() — им вовсе не нужно модифицировать файлы ядра.
Это дает вполне осязаемую практическую пользу. Когда ядро WordPress обновляется (автоматически или вручную), его файлы целиком заменяются на новую версию. Любые изменения, внесенные напрямую в файлы ядра, были бы молча стерты при следующем обновлении. Кастомизация же через хуки живет в отдельном файле (в каталогах wp-content/themes/ или wp-content/plugins/ ), полностью изолированном от ядра — поэтому она переживает любые обновления ядра в неприкосновенности.
Итог
| Тип | Назначение | Возвращаемое значение | Пример из этого блога |
|---|---|---|---|
| Экшен | Выполнить код в определенный момент | Отсутствует (только побочные эффекты) |
save_post → предварительная генерация OGP-изображения |
| Фильтр | Изменить значение, переданное ядром | Измененное значение |
excerpt_length → изменение количества слов в анонсе на 60 |
Экшены и фильтры в совокупности представляют собой тот самый механизм, который позволяет ядру WordPress, плагинам и темам взаимодействовать друг с другом, не изменяя чужой исходный код. Когда вы читаете незнакомый код на WordPress, обычно достаточно проверить всего две вещи: является ли это add_action или add_filter и на каком хуке это зарегистрировано — чтобы точно понять, в какой момент потока выполнения ядра происходит перехват и как именно.
Комментарии (0)
Пока нет комментариев — будьте первым.