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

В WordPress хук pre_get_posts — один из самых мощных инструментов для изменения основного запроса на вывод записей. Он позволяет гибко настраивать выборку постов на страницах архива, главной, в поиске и других местах без необходимости создавать собственные запросы с нуля.

Что такое pre_get_posts и зачем его использовать для фильтров

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

Например, если вам нужно реализовать сложные фильтры по нескольким таксономиям и метаполям, или исключить из выборки определённые записи, вы можете сделать это централизованно через этот хук.

Важно помнить, что pre_get_posts срабатывает везде, где используется WP_Query, поэтому нужно обязательно проверять, что вы меняете именно нужный запрос — например, основной запрос на странице архива.

Пример: создание сложного AJAX-фильтра с таксономиями и метаполями

Рассмотрим практический пример, как с помощью pre_get_posts реализовать фильтр записей по нескольким параметрам — категориям, тегам и кастомному метаполю «цена».

Для начала добавим обработчик в functions.php вашей темы или плагина:

function wplessons_pre_get_posts_filter(\WP_Query $query) {
    // Проверяем, что это не админка и основной запрос
    if (is_admin() || !$query->is_main_query()) {
        return;
    }

    // Пример: применяем фильтр только на главной странице архива записей
    if (is_post_type_archive('post') || is_home()) {
        $tax_query = [];
        $meta_query = [];

        // Фильтр по категориям, переданным в URL, например ?cat_filter=5,7
        if (!empty($_GET['cat_filter'])) {
            $cats = array_map('intval', explode(',', $_GET['cat_filter']));
            $tax_query[] = [
                'taxonomy' => 'category',
                'field'    => 'term_id',
                'terms'    => $cats,
                'operator' => 'IN',
            ];
        }

        // Фильтр по тегам, например ?tag_filter=wordpress,php
        if (!empty($_GET['tag_filter'])) {
            $tags = array_map('sanitize_text_field', explode(',', $_GET['tag_filter']));
            $tax_query[] = [
                'taxonomy' => 'post_tag',
                'field'    => 'slug',
                'terms'    => $tags,
                'operator' => 'IN',
            ];
        }

        // Фильтр по метаполю 'price', например ?price_min=100&price_max=500
        $price_min = isset($_GET['price_min']) ? (float)$_GET['price_min'] : 0;
        $price_max = isset($_GET['price_max']) ? (float)$_GET['price_max'] : 0;
        if ($price_min || $price_max) {
            $meta_query[] = [
                'key'     => 'price',
                'value'   => [$price_min, $price_max],
                'compare' => 'BETWEEN',
                'type'    => 'NUMERIC',
            ];
        }

        if ($tax_query) {
            $query->set('tax_query', $tax_query);
        }

        if ($meta_query) {
            $query->set('meta_query', $meta_query);
        }

        // Дополнительные настройки сортировки
        if (!empty($_GET['orderby'])) {
            $orderby = sanitize_text_field($_GET['orderby']);
            if ($orderby === 'price') {
                $query->set('orderby', 'meta_value_num');
                $query->set('meta_key', 'price');
                $query->set('order', 'ASC');
            } elseif ($orderby === 'date') {
                $query->set('orderby', 'date');
                $query->set('order', 'DESC');
            }
        }
    }
}
add_action('pre_get_posts', 'wplessons_pre_get_posts_filter');

В этом коде мы строим два массива tax_query и meta_query в зависимости от параметров GET, переданных в URL. Это позволяет динамически менять выборку без создания дополнительных WP_Query.

Пояснение к параметрам фильтрации

  • cat_filter — список ID категорий, по которым нужно отфильтровать посты
  • tag_filter — список слуг тегов для фильтрации
  • price_min и price_max — диапазон для числового метаполя «price»
  • orderby — сортировка по цене или дате

Как использовать фильтр на фронтенде с AJAX

Для удобства пользователей фильтр часто делают AJAX-формой, чтобы при выборе параметров страница не перезагружалась. В этом случае нужно отправлять параметры на сервер и перезаписывать содержимое списка записей.

Например, используя jQuery, можно сделать примерно так:

jQuery(document).ready(function($) {
    $('#filter-form').on('change', 'select, input', function() {
        var data = $('#filter-form').serialize();
        $.ajax({
            url: window.location.href,
            data: data,
            type: 'GET',
            success: function(response) {
                var newContent = $(response).find('#posts-container').html();
                $('#posts-container').html(newContent);
            }
        });
    });
});

Здесь #filter-form — форма с фильтрами, а #posts-container — контейнер с выводом записей. AJAX-запрос обновляет этот блок без полной перезагрузки.

Оптимизация и тонкости работы с pre_get_posts

Несмотря на мощь pre_get_posts, важно помнить о нескольких моментах:

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

Также для визуализации фильтров на сайте можно использовать специализированные плагины, например, ABC Pagination — отличный инструмент для улучшения навигации по фильтрованным постам.

Заключение

Использование pre_get_posts — это самый правильный способ реализовать сложное фильтрование записей в WordPress без прямого вмешательства в SQL-запросы. Применяйте проверку условий, комбинируйте таксономии и метаполя, и не забывайте про оптимизацию.

Если хотите автоматизировать создание контента с фильтрами или улучшить UX, обратите внимание на плагины из каталога WPSHOP, которые помогут сделать ваш сайт ещё удобнее и функциональнее.

Как использовать AJAX в WordPress для отображения сообщений об ошибках без перезагрузки страницы
08.12.2025
Как создать собственный вид регистрации в WordPress с помощью плагинов
10.11.2025
Как изменить название пользовательского поля в WordPress без плагинов
22.02.2026
Как удалить или изменить автора старой записи в WordPress
13.01.2026
Как отключить Gutenberg и вернуть классический редактор WordPress
09.02.2026