Как использовать хук pre_get_posts для фильтрации выводимых постов в WordPress

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

Хук pre_get_posts позволяет изменять параметры основного запроса WordPress до его выполнения. Это мощный инструмент для точечной фильтрации выборки постов на страницах сайта — будь то главная страница, архивы, поисковые результаты или кастомные шаблоны. В отличие от фильтрации выборки через WP_Query в шаблонах, использование pre_get_posts позволяет централизованно и эффективно модифицировать запросы без дублирования кода.

Диагностика: как проверить, что запрос можно изменить через pre_get_posts

Для начала нужно убедиться, что вы изменяете именно главный запрос, иначе можно случайно повлиять на лишние запросы (например, виджеты или дополнительные WP_Query). Для этого в функции обработчике используйте проверку:

function my_pre_get_posts_handler( \WP_Query $query ) {
    if ( ! $query->is_main_query() ) {
        return;
    }
    if ( is_admin() ) {
        return;
    }
    // Ваш код...
}
add_action( 'pre_get_posts', 'my_pre_get_posts_handler' );

Эти проверки гарантируют, что изменения будут применяться только к основному запросу на фронтенде.

Пошаговое решение: фильтрация постов по произвольному условию

Рассмотрим конкретный сценарий: нужно исключить из главной страницы посты определённой категории (например, ID категории 15). Вот рабочий пример кода в functions.php темы или плагине:

function exclude_category_from_home( \WP_Query $query ) {
    if ( ! $query->is_main_query() || is_admin() ) {
        return;
    }
    if ( $query->is_home() ) {
        // Исключаем категорию с ID 15
        $query->set( 'cat', '-15' );
    }
}
add_action( 'pre_get_posts', 'exclude_category_from_home' );

Объяснение:
- is_home() — условие для главной страницы блога;
- 'cat' => '-15' означает исключение категории с ID 15 из выборки.

Фильтрация по метаполям

Допустим, нужно вывести только посты с метаполем featured равным yes. Используем параметр meta_query:

function filter_posts_by_meta( \WP_Query $query ) {
    if ( ! $query->is_main_query() || is_admin() ) {
        return;
    }
    if ( is_archive() ) {
        $meta_query = array(
            array(
                'key' => 'featured',
                'value' => 'yes',
                'compare' => '='
            )
        );
        $query->set( 'meta_query', $meta_query );
    }
}
add_action( 'pre_get_posts', 'filter_posts_by_meta' );

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

  • Откройте фронтенд сайта на странице, где применена фильтрация (главная, архив или другая).
  • Проверьте, что посты, которые должны быть исключены, действительно отсутствуют.
  • Для метафильтрации убедитесь, что посты с нужным метазначением отображаются, а остальные — нет.
  • Включите WP_DEBUG в wp-config.php, чтобы убедиться в отсутствии ошибок PHP.
  • Вызовите var_dump($query->query_vars) в обработчике (только для теста), чтобы увидеть параметры запроса.

Частые ошибки и как их исправить

  • Изменения влияют на админку: не забывайте проверять is_admin(), иначе фильтрация может сломать админские запросы.
  • Изменение не применяется: убедитесь, что is_main_query() возвращает true, иначе вы редактируете не тот запрос.
  • Неправильные параметры запроса: используйте правильные ключи и значения в set(), например, 'cat' => '-15' для исключения категории.
  • Конфликты с плагинами: некоторые плагины жестко задают параметры запроса, в таких случаях фильтрация через pre_get_posts может не сработать.

Практические советы по безопасности и производительности

  • Не выполняйте сложные или ресурсоёмкие операции внутри обработчика pre_get_posts, так как он срабатывает при каждом запросе.
  • Для сложных фильтров используйте кэширование результатов запросов, например, через Transient API.
  • При фильтрации по метаполям добавьте индексы в таблицу wp_postmeta, если это возможно, для ускорения запросов.
  • Не делайте фильтрацию на страницах, где это не нужно — всегда ограничивайте условиями (например, is_home(), is_archive()).

Сравнение методов фильтрации постов

МетодПлюсыМинусыКогда использовать
pre_get_postsЦентрализованное управление, эффективное изменение главного запросаМожет влиять на все запросы, если не фильтровать правильноФильтрация постов на уровне основного запроса
WP_Query в шаблонеЛокальное переопределение выборкиДублирование кода, сложность поддержкиВывод дополнительного списка постов
Фильтрация после выборки (PHP)Гибкость в обработкеНагрузка на сервер, медленнееРедкие случаи, когда нельзя изменить запрос

Добавь в закладки и поделись с друзьями:

⭐⭐⭐⭐⭐
WooCommerce: автоматическое изменение стоимости товаров при акциях через хуки
15.06.2026
Автоматическое удаление устаревших данных через Transient API в WordPress
22.03.2026
WooCommerce: автоматическое изменение стоимости товаров при акциях через код
08.06.2026
Как создать плагин для автоматического сохранения changelogов в WordPress
30.11.2025
Как автоматизировать сборку и оптимизацию картинок в WordPress
19.12.2025
×
Сделай свой сайт крутым!

Скидка -20% на премиум плагины WordPress

Выбрать плагин сейчас ⋙