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

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

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

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

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

Если вам нужно:

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

— значит, pre_get_posts подходит идеально.

Проверить, что именно формируется запрос, можно с помощью отладки:

add_action('pre_get_posts', function($query) {
    if ($query->is_main_query() && !is_admin()) {
        error_log(print_r($query, true));
    }
});

Логи будут в debug.log, если включён WP_DEBUG_LOG.

Пошаговое решение: пример изменения главного запроса

Допустим, нужно на главной странице вывести только 5 последних постов из категории «Новости» и исключить записи с тегом «архив».

add_action('pre_get_posts', 'wpfront_modify_main_query');
function wpfront_modify_main_query($query) {
    if ($query->is_main_query() && !is_admin() && $query->is_home()) {
        $query->set('posts_per_page', 5);
        $query->set('category_name', 'novosti');
        $query->set('tag__not_in', array(get_term_by('slug', 'arhiv', 'post_tag')->term_id));
    }
}

Объяснение:

  • $query->is_main_query() — проверка, что меняется основной запрос.
  • !is_admin() — исключаем админ-панель.
  • $query->is_home() — таргетируем главную страницу.
  • Далее через set меняем параметры запроса.

Изменение запроса WooCommerce

Для изменения вывода товаров на странице магазина:

add_action('pre_get_posts', 'wpfront_modify_shop_query');
function wpfront_modify_shop_query($query) {
    if (!is_admin() && $query->is_main_query() && is_post_type_archive('product')) {
        // Показывать только товары с ценой > 1000
        $meta_query = array(
            array(
                'key'     => '_price',
                'value'   => 1000,
                'compare' => '>',
                'type'    => 'NUMERIC'
            )
        );
        $query->set('meta_query', $meta_query);
        $query->set('posts_per_page', 12);
    }
}

Как проверить, что изменения работают

  • Убедитесь, что код добавлен в functions.php темы или в кастомный плагин.
  • Очистите кеш сайта и браузера.
  • Обновите страницу, на которую направлен запрос (например, главную или архив товаров).
  • Проверьте, что изменилось количество или фильтрация постов.
  • Если нужно, включите WP_DEBUG и WP_DEBUG_LOG для отладки.

Частые ошибки при работе с pre_get_posts и их решения

  • Изменение не работает на странице админки: Не забывайте проверять !is_admin(), чтобы не влиять на запросы в панели управления.
  • Применяется не к главному запросу: Всегда используйте $query->is_main_query() для точного таргетинга.
  • Неверные параметры запроса: Проверьте, что используете правильные ключи и значения. Например, tag__not_in принимает массив ID тегов, а не слаг.
  • Проблемы с мета-запросами: Метаполя должны существовать и быть правильно типизированы (например, 'NUMERIC' для чисел).

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

  • Не используйте pre_get_posts для сложных выборок с большими мета-запросами без индексов — это замедлит сайт.
  • Ограничивайте области действия хука через проверки, чтобы не влиять на лишние запросы.
  • Избегайте тяжелых функций и лишних циклов внутри функции, подключенной к pre_get_posts.
  • При необходимости используйте transient API для кеширования результатов сложных запросов.

Сравнение способов изменения запросов WordPress

МетодПлюсыМинусыКогда использовать
pre_get_postsИзменяет основной запрос без перезаписи шаблонов, гибкоНужно правильно фильтровать запросы, сложнее отладкаДля изменения отображения стандартных архивов и страниц
Создание нового WP_QueryПолный контроль, можно создавать дополнительные выборкиНе влияет на основной запрос, дублирование кодаДля вывода дополнительных блоков на странице
WP_Query с фильтрами SQLМаксимальная гибкостьСложно поддерживать, риски безопасностиКогда нужны нестандартные запросы, не поддерживаемые API
Как добавить автоматическое заполнение формы в WordPress
09.02.2026
Как удалить кеш из браузера после изменений в WordPress
09.03.2026
Как создать автоматические ответы на часто задаваемые вопросы в WordPress
20.12.2025
Как удалить черновики в WordPress без плагинов
22.01.2026
Как удалить старые ревизии постов в WordPress из базы данных
26.01.2026