Хуки WordPress: actions и filters — что это и как использовать новичку

Хуки WordPress: actions и filters — что это и как использовать новичку

Быстрый ответ: Хуки (hooks) в WordPress — это точки «подключения», через которые вы встраиваете свой код в работу движка, не трогая его ядро. Есть два типа хуков: actions (события) — выполняют вашу функцию в нужный момент, и filters (фильтры) — принимают и изменяют данные. Базовый синтаксис — add_action('init', 'my_function') и add_filter('the_content', 'my_function'). Код добавляют в functions.php дочерней темы или в собственный плагин. Понимание хуков — ключ к любой кастомизации WordPress: от мелких правок текста до изменения логики WooCommerce.

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

Что такое хуки и зачем они нужны

Представьте конвейер: WordPress выполняет запрос, загружает тему, собирает страницу и отдаёт её посетителю. Хуки — это «крючки», расставленные по всему этому конвейеру. В определённые моменты WordPress «останавливается» и спрашивает: «Кто-нибудь хочет здесь вмешаться?»

Технически хук — это зарегистрированное в коде событие, на которое вы «вешаете» свою функцию. Когда WordPress доходит до этого места, он вызывает все функции, привязанные к хуку. Так вы добавляете свою логику без правки ядра: обновление WordPress не сотрёт ваши изменения, потому что они лежат в теме или плагине.

Главные плюсы работы через хуки:

  • Безопасные обновления. Ядро и плагины можно обновлять — ваш код в functions.php не потеряется.
  • Модульность. Логика разбивается на мелкие функции, которые легко включать и отключать.
  • Совместимость. Вы работаете с официальным API, а не с «костылями» через правку чужих файлов.
  • Переиспользование. Один и тот же сниппет легко перенести на другой сайт.

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

Actions и filters: в чём разница

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

Actions (события) — это моменты времени, когда что-то происходит: сайт инициализировался, запись опубликована, подключены скрипты. Обработчик action просто выполняет код и ничего не возвращает. Его задача — «сделать что-то»: зарегистрировать тип записи, добавить скрипт, отправить письмо.

Filters (фильтры) — это точки, где WordPress «прогоняет» данные через вашу функцию. Обработчик фильтра обязательно принимает значение, изменяет его и возвращает обратно. Задача фильтра — «поменять что-то»: текст записи, длину анонса, список классов меню.

Простой пример разницы:

// ACTION — выполняет действие (ничего не возвращает)
function my_send_notification() {
    wp_mail( 'admin@example.com', 'Новая запись', 'Опубликована новая запись' );
}
add_action( 'publish_post', 'my_send_notification' );

// FILTER — принимает значение и возвращает изменённое
function my_extend_excerpt( $length ) {
    return 40; // меняем длину анонса на 40 слов
}
add_filter( 'excerpt_length', 'my_extend_excerpt' );

Обратите внимание: в первом случае функция ничего не возвращает — она просто «срабатывает». Во втором — принимает $length и обязательно возвращает новое значение через return. Если фильтр забудет вернуть значение, WordPress получит null и данные сломаются.

add_action и add_filter: базовый синтаксис

Чтобы «повесить» свою функцию на хук, используют две функции. Их синтаксис почти идентичен.

add_action( $hook_name, $callback, $priority, $accepted_args );
add_filter( $hook_name, $callback, $priority, $accepted_args );

Разберём параметры:

  • $hook_name — имя хука, например 'init' или 'the_content'.
  • $callback — имя вашей функции (строка) или анонимная функция.
  • $priority — приоритет (число, по умолчанию 10). Чем меньше число, тем раньше выполнится функция.
  • $accepted_args — сколько аргументов ваша функция принимает (по умолчанию 1).

Минимальный рабочий пример — выведем текст в подвале сайта:

function my_footer_text() {
    echo '<p>Сделано с любовью к WordPress</p>';
}
add_action( 'wp_footer', 'my_footer_text' );

Хук wp_footer срабатывает перед закрывающим тегом </body>, поэтому ваш текст появится в самом низу каждой страницы. А вот пример анонимной функции (доступно начиная с PHP 5.3):

add_action( 'wp_footer', function() {
    echo '<p>Этот текст тоже в подвале</p>';
} );

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

Пять практических примеров actions

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

1. Регистрация кастомного типа записи

Хук init — самый «ранний» и популярный. На него вешают регистрацию типов записей и таксономий:

function my_register_portfolio_type() {
    register_post_type( 'portfolio', array(
        'label'       => 'Портфолио',
        'public'      => true,
        'has_archive' => true,
        'supports'    => array( 'title', 'editor', 'thumbnail' ),
    ) );
}
add_action( 'init', 'my_register_portfolio_type' );

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

2. Подключение стилей и скриптов

Правильный способ добавить CSS и JS на сайт — хук wp_enqueue_scripts. Не вставляйте <link> и <script> напрямую в шапку темы.

function my_theme_assets() {
    wp_enqueue_style( 'my-style', get_stylesheet_uri() );
    wp_enqueue_script( 'my-script', get_stylesheet_directory_uri() . '/js/main.js', array( 'jquery' ), '1.0', true );
}
add_action( 'wp_enqueue_scripts', 'my_theme_assets' );

Здесь wp_enqueue_style подключает стиль, а wp_enqueue_script — скрипт с зависимостью от jQuery. Последний параметр true ставит скрипт в подвал, что ускоряет загрузку.

3. Уведомление администратора о новом комментарии

Хук wp_insert_comment срабатывает при добавлении комментария:

function my_notify_new_comment( $comment_id ) {
    $comment = get_comment( $comment_id );
    wp_mail( get_option( 'admin_email' ), 'Новый комментарий', 'Автор: ' . $comment->comment_author );
}
add_action( 'wp_insert_comment', 'my_notify_new_comment' );

4. Отложенная отправка писем через cron

Чтобы не грузить страницу, тяжёлые задачи вешают на расписание WordPress (WP-Cron) — это тоже хуки:

// Планируем задачу раз в час
function my_schedule_task() {
    if ( ! wp_next_scheduled( 'my_hourly_task' ) ) {
        wp_schedule_event( time(), 'hourly', 'my_hourly_task' );
    }
}
add_action( 'init', 'my_schedule_task' );

// Сама задача
add_action( 'my_hourly_task', 'my_run_cleanup' );
function my_run_cleanup() {
    // например, удаляем устаревшие транзиенты
    delete_expired_transients();
}

5. Добавление пункта в админ-меню

function my_admin_menu_item() {
    add_menu_page(
        'Мои настройки',
        'Мои настройки',
        'manage_options',
        'my-settings',
        'my_settings_page_callback',
        'dashicons-admin-generic',
        25
    );
}
add_action( 'admin_menu', 'my_admin_menu_item' );

Пять практических примеров filters

Фильтры меняют данные. Вот самые полезные для новичка.

1. Изменить текст записи

Фильтр the_content вызывается при выводе содержимого записи. Можно, например, добавлять подпись в конец каждой статьи:

function my_append_signature( $content ) {
    if ( is_single() ) {
        $content .= '<p><em>Статья подготовлена командой delai-sait.ru</em></p>';
    }
    return $content;
}
add_filter( 'the_content', 'my_append_signature' );

Здесь важно return $content — без него весь контент записи превратится в пустоту.

2. Изменить длину анонса

function my_excerpt_length( $length ) {
    return 35;
}
add_filter( 'excerpt_length', 'my_excerpt_length' );

3. Заменить текст в анонсе «[…]»

function my_excerpt_more( $more ) {
    return ' … <a href="' . get_permalink() . '">Читать далее</a>';
}
add_filter( 'excerpt_more', 'my_excerpt_more' );

4. Добавить класс к body

function my_body_class( $classes ) {
    $classes[] = 'my-custom-class';
    return $classes;
}
add_filter( 'body_class', 'my_body_class' );

Обратите внимание: $classes — это массив, поэтому мы добавляем элемент и возвращаем массив целиком.

5. Изменить текст кнопки WooCommerce

Практически весь WooCommerce построен на хуках, поэтому менять его поведение можно без правки файлов плагина:

function my_change_add_to_cart_text( $text ) {
    return 'Купить сейчас';
}
add_filter( 'woocommerce_product_single_add_to_cart_text', 'my_change_add_to_cart_text' );

Если работаете с магазином, изучите хуки WooCommerce — это сэкономит десятки часов. Статья про заказ интернет-магазина на WordPress объяснит, где заканчивается стандартная функциональность и начинается кастомизация.

Приоритеты и количество аргументов

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

add_action( 'wp_footer', 'first_function', 5 );   // выполнится первой
add_action( 'wp_footer', 'second_function', 10 );  // выполнится второй
add_action( 'wp_footer', 'third_function', 20 );   // выполнится последней

Приоритет критичен, когда ваша функция должна «дождаться», пока другой плагин что-то зарегистрирует. Например, если вы отключаете стиль плагина, добавленный с приоритетом 10, ваш wp_dequeue_style должен иметь приоритет 20 или выше.

Второй важный параметр — $accepted_args. По умолчанию WordPress передаёт функции один аргумент. Если хук передаёт несколько значений, а вам нужны все — укажите количество:

// Хук save_post передаёт три аргумента
function my_on_save( $post_id, $post, $update ) {
    // используем все три
}
add_action( 'save_post', 'my_on_save', 10, 3 );

Без , 3 в конце функция получит только $post_id, а остальные аргументы будут проигнорированы. Это частая причина «почему мой код не работает».

Свои хуки: do_action и apply_filters

Хуки можно не только использовать, но и создавать. Это полезно, когда вы делаете плагин или тему и хотите, чтобы другие могли их расширять.

Для создания action используют do_action:

// В вашем плагине
function my_payment_success( $order_id ) {
    // логика оплаты...
    do_action( 'my_after_payment', $order_id );
}

Теперь любой другой плагин может подписаться на ваше событие:

add_action( 'my_after_payment', function( $order_id ) {
    wp_mail( 'admin@example.com', 'Оплата получена', 'Заказ #' . $order_id );
} );

Для создания filter используют apply_filters:

// В вашей теме: даём возможность изменить цену
$price = apply_filters( 'my_product_price', $base_price, $product_id );

Пользователь темы может подменить цену:

add_filter( 'my_product_price', function( $price, $product_id ) {
    return $price * 0.9; // скидка 10%
}, 10, 2 );

Создание собственных хуков — признак «взрослого» кода: так строят архитектуру популярные плагины вроде WooCommerce или ACF.

Сравнительная таблица: actions vs filters

Критерий Action (событие) Filter (фильтр)
Назначение Выполнить действие в нужный момент Изменить передаваемые данные
Что делает функция Выполняет код, ничего не возвращает Принимает значение и возвращает изменённое
Ключевое слово add_action / do_action add_filter / apply_filters
Возврат значения Не требуется (игнорируется) Обязателен (return)
Типичные примеры init, wp_enqueue_scripts, wp_footer the_content, excerpt_length, body_class
Последствие ошибки Код просто не выполнится Данные станут пустыми или сломаются

На практике многие хуки работают «и так, и так»: например, add_action и add_filter внутри ядра — это одна и та же функция add_filter(), просто с разными обёртками. Но семантически разницу стоит соблюдать, чтобы код читался правильно.

Куда добавлять код: functions.php или плагин

Вопрос «куда положить сниппет» — один из самых частых у новичков. Короткий ответ: в дочернюю тему или в отдельный плагин, но никогда в файлы ядра или родительской темы.

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

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

<?php
/**
 * Plugin Name: My Custom Hooks
 * Description: Мои сниппеты для кастомизации сайта.
 * Version: 1.0
 */

// здесь ваши add_action и add_filter

Файл кладут в wp-content/plugins/my-custom-hooks/ и активируют в админке. Такой подход удобен, когда вы переносите сайт или тестируете функциональность в песочнице.

Готовые сниппеты для functions.php, которые решают типовые задачи новичка, собраны в статье про полезные сниппеты для functions.php.

Частые ошибки новичков

  1. Забытый return в фильтре. Фильтр без return ломает данные. Всегда возвращайте значение.
  2. Неправильное имя хука. Опечатка в 'the_content' или 'init' — и функция молча не выполняется. Сверяйтесь со списком хуков в документации WordPress.
  3. Слишком много аргументов без $accepted_args. Если хук передаёт два значения, а вы читаете оба, но не указали , 2 — второй будет пустым.
  4. Правка файлов ядра. Никогда не редактируйте wp-includes или файлы родительской темы — изменения сотрутся при обновлении. Только дочерняя тема или плагин.
  5. Хуки в неправильном месте файла. add_action должен быть на верхнем уровне functions.php, а не внутри другой функции, которая ещё не вызвана.
  6. Игнорирование приоритета. Код «не работает», потому что другой плагин с более высоким приоритетом перезаписывает результат. Поднимите свой приоритет.

TimeWeb

Часто задаваемые вопросы

В чём разница между action и filter простыми словами?

Action — это «сделай что-то»: выполнить код в нужный момент, ничего не возвращая. Filter — это «поменяй что-то»: принять значение, изменить его и вернуть обратно. Action регистрируют через add_action, filter — через add_filter.

Куда добавлять код с хуками — в functions.php или в плагин?

Для правок конкретного сайта используйте functions.php дочерней темы. Если сниппет должен работать независимо от темы и сохраняться при её смене — вынесите его в отдельный плагин. Никогда не редактируйте файлы ядра и родительской темы.

Что будет, если фильтр не вернёт значение?

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

Зачем нужен параметр $accepted_args?

Он указывает, сколько аргументов хука должна принять ваша функция. По умолчанию передаётся один. Если хук передаёт три значения, а вы используете все три, нужно явно указать add_action(‘save_post’, ‘my_func’, 10, 3).

Можно ли отключить хук, добавленный плагином?

Да. Используйте remove_action() или remove_filter() с тем же именем хука и функции, причём с тем же приоритетом, с которым хук был добавлен. Это удобный способ отключить ненужную функциональность плагина без правки его файлов.

Как узнать, какие хуки есть в WordPress?

Официальная документация WordPress (developer.wordpress.org/reference/hooks/) содержит полный список actions и filters с примерами. Для WooCommerce свой список хуков в документации плагина. Также помогает поиск по коду — например, ищите do_action и apply_filters в исходниках нужного плагина.

Вывод

Хуки — это язык, на котором «говорят» темы и плагины WordPress. Освоив add_action и add_filter, вы перестаёте зависеть от готовых решений и начинаете менять поведение сайта под задачу: от мелкой правки текста кнопки до сложной логики интеграций. Начните с простого — добавьте пару сниппетов в functions.php дочерней темы, поэкспериментируйте с приоритетами и обязательно проверяйте, что каждый фильтр возвращает значение.

Нужна кастомизация под ключ или помощь с разработкой? Команда студии «Делай Сайт» реализует функциональность любой сложности — от сниппетов до разработки сайта под ключ. Посмотрите наше портфолио или свяжитесь с нами — подскажем, как правильно спроектировать ваш проект.

Статья написана для блога delai-sait.ru — разработка и поддержка сайтов на WordPress.

Clearfy

Поделиться:
Telegram ВКонтакте