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

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

Хук pre_get_posts позволяет изменить главный WP_Query до выполнения запроса к базе. С его помощью можно фильтровать записи, изменять параметры выборки, например, ограничить вывод по категориям, меткам, типу записи и другим условиям. Это самый гибкий способ программно влиять на контент, который выводится на фронтенде и в административной части.

Диагностика: когда нужен pre_get_posts

Если на сайте WordPress нужно:

  • показывать на главной странице или архиве только определённые записи;
  • исключать из вывода записи по определённым условиям (например, по меткам, авторам, пользовательским полям);
  • менять сортировку или количество записей;
  • фильтровать результаты поиска;

— то pre_get_posts — ваш инструмент. Если пытаться менять query_posts() или другие методы, это может привести к ошибкам и конфликтам.

Пошаговое решение: базовое использование pre_get_posts

1. Добавляем функцию в файл functions.php вашей темы

function wpboot_filter_main_query( \WP_Query $query ) {
    // Применяем только к главному запросу на фронтенде
    if ( ! is_admin() && $query->is_main_query() ) {
        // Пример: выводим только записи из категории с ID 5
        $query->set( 'cat', 5 );
        // Можно изменить количество постов на 10
        $query->set( 'posts_per_page', 10 );
    }
}
add_action( 'pre_get_posts', 'wpboot_filter_main_query' );

2. Проверяем работу

Откройте главную страницу сайта в браузере. Вы должны увидеть только записи из категории с ID 5 и не более 10 штук. Если изменений нет, проверьте, что функция подключена и не перезаписывается другими плагинами.

Расширенные примеры фильтрации

Фильтрация по метаполю (кастомному полю)

function wpboot_filter_by_meta_key( \WP_Query $query ) {
    if ( ! is_admin() && $query->is_main_query() && is_post_type_archive( 'product' ) ) {
        $meta_query = [
            [
                'key' => 'in_stock',
                'value' => '1',
                'compare' => '=',
            ],
        ];
        $query->set( 'meta_query', $meta_query );
    }
}
add_action( 'pre_get_posts', 'wpboot_filter_by_meta_key' );

Этот код на архиве типа записи “product” отфильтрует товары, у которых метаполе in_stock равно 1.

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

Для проверки результата:

  • Откройте страницу, на которую влияет фильтр (например, главную или архив);
  • Выведите в шаблоне var_dump($wp_query->request) для отладки SQL-запроса;
  • Проверьте в админке, что фильтрация не влияет на административные запросы (если это не нужно);
  • Воспользуйтесь плагином Query Monitor для мониторинга запросов и фильтров.

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

  • Использование pre_get_posts без проверки is_main_query()
    Без проверки фильтр может применяться к вспомогательным запросам, ломая вывод других элементов. Всегда добавляйте if ($query->is_main_query()).
  • Не учитывается is_admin()
    Если не исключить админку (! is_admin()), фильтрация затронет запросы в панели, что может привести к ошибкам.
  • Неверные параметры запроса
    Параметры должны соответствовать WP_Query. Например, для категорий используйте cat с ID или category_name с ярлыком.
  • Конфликты с другими плагинами или темами
    Проверьте, не перезаписывают ли другие фильтры запросы. Отключите плагины поочерёдно для диагностики.

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

  • Минимизируйте количество сложных метазапросов (meta_query), они замедляют SQL.
  • Используйте кеширование результатов WP_Query (например, объектный кеш) для часто запрашиваемых страниц.
  • Не создавайте бесконечные циклы — pre_get_posts меняет запросы, будьте внимательны при вызове новых запросов внутри фильтра.

Сравнение способов фильтрации контента в WordPress

МетодПреимуществаНедостатки
pre_get_postsГибкая фильтрация, работает до запроса, не влияет на шаблоныТребует аккуратности, может конфликтовать с другими фильтрами
query_posts()Простой вызов переопределения запросаПерезаписывает глобальный запрос, может ломать пагинацию
WP_Query внутри шаблонаИзолированный запрос, не влияет на главный запросДополнительные запросы к БД, повышенная нагрузка
WooCommerce: автоматическое изменение цены товара при применении купона
08.06.2026
Удаление всех вариаций товара в WooCommerce через код
16.05.2026
Оценка производительности WordPress без плагинов: практические способы и примеры
10.01.2026
Как добавить переадресацию в WordPress без плагинов
26.01.2026
Замена AJAX на Fetch API в WordPress Gutenberg
05.04.2026