Как использовать метод pre_get_posts для контроля запросов в WordPress

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

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

Типичные задачи с pre_get_posts

  • Исключение определенных категорий из главного цикла
  • Показ только определенных типов записей на страницах архива
  • Изменение количества записей на странице для конкретного шаблона
  • Фильтрация записей по пользовательским метаданным или таксономиям

Диагностика проблемы: почему pre_get_posts не работает

Частая ошибка — хуки не срабатывают, либо изменения не отражаются на сайте. Основные причины:

  • Неправильное использование глобального объекта $query
  • Изменение не главного запроса (is_main_query())
  • Привязка хука на неправильный приоритет или в неподходящем месте (например, слишком рано или поздно)
  • Конфликты с другими плагинами или темами

Проверка: добавьте в функцию error_log() или var_dump(), чтобы убедиться, что хук вызывается и что передается нужный объект запроса.

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

Рассмотрим пример — исключить из главной страницы записи из категории с ID 10 и изменить количество записей на 5.

function wpdocs_modify_main_query( $query ) {
    if ( ! is_admin() && $query->is_main_query() ) {
        if ( $query->is_home() ) {
            // Исключаем категорию с ID 10
            $query->set( 'cat', '-10' );
            // Устанавливаем количество записей на странице
            $query->set( 'posts_per_page', 5 );
        }
    }
}
add_action( 'pre_get_posts', 'wpdocs_modify_main_query' );

Обратите внимание на проверку ! is_admin() и $query->is_main_query() — без них изменения могут примениться к административной панели или к дополнительным запросам.

Другой пример: фильтрация по пользовательскому метаполю

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

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

  • Обновите главную страницу (или нужный архив) и убедитесь, что записи из категории 10 отсутствуют.
  • Проверьте, что на странице выводится ровно 5 записей.
  • Используйте Query Monitor или аналогичный плагин для просмотра параметров текущего запроса.
  • Для мета-фильтрации убедитесь, что возвращаются только записи с заданным значением метаполя.

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

  • Изменения не видны на фронтенде: забыли проверку $query->is_main_query() или использовали хук слишком рано.
  • Изменения влияют на админку: не добавили условие ! is_admin().
  • Конфликт с другими плагинами: попробуйте отключить остальные плагины и проверить работу вашего кода.
  • Неправильные параметры запроса: внимательно проверьте передаваемые в $query->set() значения, особенно для сложных параметров — таксономии, метазапросы.

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

  • Всегда проверяйте is_main_query(), чтобы не ломать админку и не влиять на дополнительные запросы.
  • Для сложной логики лучше использовать отдельные функции и четко документировать изменения.
  • Тестируйте на разных страницах — главная, архивы, страницы поиска.
  • Используйте WP_Query или get_posts для кастомных запросов, если не хотите менять главный запрос.
  • Для безопасности и производительности избегайте тяжелых метазапросов без индексации базы.

Сравнение вариантов управления запросами в WordPress

МетодГде используетсяПлюсыМинусы
pre_get_postsГлавный WP_Query и дополнительные запросыГибкое изменение условий выборки без перезапуска запросаМожно нарушить логику, если нет проверок
WP_QueryКастомные запросы в шаблонах и плагинахПолный контроль, не влияет на главный запросДублирование запросов, возможное снижение производительности
get_postsПростые выборки, мелкие запросыПростота использования, возвращает массив объектовМеньше контроля, не подходит для сложных фильтров
Как использовать WPStories для создания интерактивных историй в WordPress
08.03.2026
Как создать кастомный виджет в WordPress
02.12.2025
Как настроить отложенный запуск задач в WordPress без WP-Cron
12.02.2026
Как использовать WP REST API для автоматического обновления товаров WooCommerce
01.05.2026
Автоматическое изменение цены товара при обновлении в WooCommerce
22.04.2026