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

Что такое фильтр pre_get_posts и для чего он нужен

Фильтр pre_get_posts позволяет изменить основной запрос WordPress перед его выполнением. Это мощный инструмент для тонкой настройки выборки записей без создания новых WP_Query. Чаще всего его используют, чтобы изменить поведение главной страницы, архивов, поисковых результатов, страниц категории или кастомных таксономий.

Диагностика задачи: когда и почему стоит использовать pre_get_posts

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

Чтобы понять, что фильтр pre_get_posts вам подходит:

  • Проверьте, не работает ли уже основной запрос (например, на главной или архивной странице)
  • Убедитесь, что результат нужно изменить глобально, а не локально в одном месте
  • Если пагинация ломается после кастомных WP_Query — это признак, что стоит поправить через pre_get_posts

Пошаговое решение: пример фильтрации главной страницы по исключению категории

Задача: исключить из главной страницы записи из категории с ID 15.

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

Объяснение:

  • Проверяем, что мы не в админке (! is_admin())
  • Работаем только с основным запросом ($query->is_main_query())
  • Применяем только на главной странице ($query->is_home())
  • Через параметр cat передаём ID категории со знаком минус для исключения

Другой пример — добавление пользовательского мета-запроса

Если нужно показывать только записи, где мета-поле featured равно 1 на странице архива кастомного типа записей product:

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

Как проверить, что фильтр сработал

  • Откройте страницу, на которую воздействует фильтр (например, главную)
  • Убедитесь, что записи из исключённых категорий не отображаются
  • Для проверки мета-запроса проверьте, что выводятся только записи с заданным мета-полем
  • Включите режим отладки: добавьте var_dump($query->request) в файл functions.php после установки параметров в фильтре, чтобы увидеть SQL-запрос
  • Проверьте пагинацию — она должна работать корректно после применения фильтра

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

  • Изменение не основного запроса: не используйте фильтр без проверки is_main_query(), иначе изменятся все запросы, в том числе в админке и сайдбарах.
  • Применение в админке: фильтр сработает на все запросы в админке, если не добавить ! is_admin().
  • Неправильные параметры запроса: для исключения категорий используйте знак минус перед ID (-15), иначе записи будут фильтроваться наоборот.
  • Нарушение пагинации: если после фильтрации пагинация не работает, проверьте, что фильтр применяется только к основному запросу и не меняет параметры, влияющие на количество постов.

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

  • Используйте кэширование запросов, например, с помощью Object Cache или плагинов кеша, чтобы уменьшить нагрузку от сложных фильтров.
  • Избегайте сложных meta_query с большим количеством условий без индексации базы данных, так как они сильно замедляют запросы.
  • Не добавляйте тяжелые вычисления или внешние запросы внутри pre_get_posts, это влияет на время загрузки.
  • Всегда ограничивайте область действия фильтра с помощью проверок is_admin(), is_main_query() и условий для страниц.

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

МетодОписаниеПлюсыМинусы
pre_get_postsИзменение основного запроса через хукГлобальное, корректно работает с пагинацией, без дублирования WP_QueryТребует точных условий, можно повлиять на другие запросы по ошибке
Новый WP_QueryСоздание нового запроса для выборкиЛокальный контроль, можно получать любые данныеПроблемы с пагинацией, дублирование кода, сложнее поддерживать
Плагины фильтрацииГотовые решения с интерфейсомУдобство, нет нужды писать кодНагрузка, ограниченные возможности кастомизации
Как создать собственный шорткод WordPress: практическое руководство с примерами
17.11.2025
Как создать собственный плагин для мониторинга здоровья WordPress
08.04.2026
Как создать собственный виджет WordPress с примерами кода
03.12.2025
WooCommerce: не отображается описание товара после обновления — как исправить
04.05.2026
Как предотвратить дублирование заказов в WooCommerce
01.05.2026