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

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

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

Хук pre_get_posts вызывается перед выполнением основного запроса WordPress (WP_Query). Это событие даёт возможность изменить параметры запроса, например, изменить типы записей, таксономии, порядок сортировки, количество постов и многое другое.

В отличие от фильтра posts_where или posts_join, здесь мы работаем с объектом запроса, что более удобно и безопасно. Кроме того, это позволяет избежать лишних запросов к базе и улучшить производительность.

Тем не менее, с этим хуком нужно работать аккуратно, особенно если изменяется главный запрос, чтобы не нарушить работу шаблона и пагинацию.

Основные параметры WP_Query, доступные для изменения в pre_get_posts

Через объект запроса ($query) можно менять практически любые параметры WP_Query:

  • post_type — типы записей для выборки;
  • posts_per_page — количество постов на страницу;
  • order и orderby — сортировка;
  • tax_query — фильтрация по таксономиям;
  • meta_query — фильтрация по кастомным полям;
  • И другие параметры WP_Query.

Важно проверять, что мы меняем нужный запрос, обычно проверяют $query->is_main_query() или другие условия, чтобы не повлиять на админку или другие запросы.

Пример 1: Фильтрация главного запроса на главной странице

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

add_action('pre_get_posts', 'wptemy_pre_get_posts_filter_main_query');
function wptemy_pre_get_posts_filter_main_query($query) {
    if (!is_admin() && $query->is_main_query() && is_home()) {
        $query->set('post_type', 'post');
        $query->set('posts_per_page', 5);
        $query->set('order', 'DESC');
        $query->set('orderby', 'date');
    }
}

Этот код исключает из главного цикла все, кроме стандартных записей, и ограничивает вывод 5 свежими постами.

Пример 2: Фильтрация записей по таксономии в пользовательском архиве

Если у вас есть кастомный тип записей product с таксономией product_cat, и нужно вывести на архивной странице только продукты из категории «электроника».

add_action('pre_get_posts', 'wptemy_filter_products_by_category');
function wptemy_filter_products_by_category($query) {
    if (!is_admin() && $query->is_main_query() && is_post_type_archive('product')) {
        $tax_query = array(
            array(
                'taxonomy' => 'product_cat',
                'field'    => 'slug',
                'terms'    => 'elektronika',
            ),
        );
        $query->set('tax_query', $tax_query);
    }
}

Такой фильтр позволит автоматически показывать только товары из нужной категории без дополнительных параметров в URL.

Пример 3: Фильтрация по метаполям (custom fields)

Если вы хотите вывести на странице архива записи, у которых кастомное поле featured установлено в значение yes, можно использовать мета-запрос:

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

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

Практические советы при работе с pre_get_posts

  • Всегда проверяйте, что вы меняете именно нужный запрос, используя is_main_query() и условные теги (например, is_home(), is_archive(), is_post_type_archive()).
  • Не меняйте запросы в админке без крайней необходимости, чтобы избежать багов.
  • Если добавляете сложные условия с несколькими таксономиями и метаполями, объединяйте их через tax_query и meta_query с правильными параметрами relation.
  • Для дебага используйте var_dump($query); или плагины типа Query Monitor, чтобы проверить итоговые параметры запроса.

Совместимость с плагинами и темами

Если вы используете темы от WPSHOP (например, JournalX, Root или Reboot), то они корректно поддерживают стандартные хуки WordPress, включая pre_get_posts. Это значит, что ваши дополнительные фильтры не вызовут конфликтов.

В некоторых случаях полезно комбинировать pre_get_posts с плагинами для оптимизации, например, Clearfy Pro, который может помочь отключить ненужные запросы и улучшить производительность.

Заключение

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

Используйте проверку условий и внимательно тестируйте изменения, чтобы избежать проблем с отображением и пагинацией.

Как отключить AJAX в WooCommerce без плагинов
08.01.2026
Как избежать конфликтов между плагинами WordPress с примерами кода
25.01.2026
Как отключить AJAX пагинацию в WordPress без плагинов
21.12.2025
Как использовать WPRemark для отзывов в WordPress
15.01.2026
Как использовать хук pre_get_posts для фильтрации товаров в WooCommerce
21.01.2026