Как создать умный фильтр для постов WordPress с помощью WP_Query

В современном WordPress-проекте часто возникает задача создать удобный и быстрый фильтр постов по различным параметрам — категориям, таксономиям, мета-полям и другим критериям. В этой статье мы подробно разберём, как реализовать такой умный фильтр с помощью класса WP_Query, AJAX для динамического обновления результатов и PHP для обработки запросов. Этот подход позволит улучшить пользовательский опыт и ускорить работу сайта, избегая перезагрузок страниц.

Основы работы с WP_Query для фильтрации постов

Класс WP_Query — это мощный инструмент WordPress для выборки постов из базы по разным параметрам. Чтобы создать фильтр, нужно правильно сформировать аргументы запроса, учитывая выбранные пользователем значения.

Пример базового запроса, который выбирает посты из категории с ID 5 и сортирует их по дате:

$args = [
    'cat' => 5,
    'orderby' => 'date',
    'order' => 'DESC',
    'posts_per_page' => 10
];
$query = new WP_Query($args);

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

Фильтрация по категориям и мета-полям

Для фильтрации по нескольким категориям используйте параметр category__in, передавая массив ID. Для мета-полей — meta_query, где можно задавать один или несколько условий.

$args = [
    'category__in' => [5, 10],
    'meta_query' => [
        [
            'key' => 'price',
            'value' => [1000, 5000],
            'compare' => 'BETWEEN',
            'type' => 'NUMERIC'
        ]
    ],
    'posts_per_page' => 10
];

Такой запрос выберет посты из категорий 5 или 10, у которых значение мета-поля price находится в диапазоне от 1000 до 5000.

Реализация AJAX-запроса для динамического обновления фильтра

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

Сначала создадим JS-скрипт, который будет отправлять выбранные параметры фильтра на сервер и обновлять список постов:

jQuery(document).ready(function($) {
    $('#filter-form').on('change', 'input, select', function() {
        var data = $('#filter-form').serialize();
        $.ajax({
            url: ajaxurl, // определён в wp_localize_script
            type: 'POST',
            data: data + '&action=wpquery_filter_posts',
            success: function(response) {
                $('#posts-container').html(response);
            }
        });
    });
});

Обратите внимание, что в PHP мы добавим обработчик с именем wpquery_filter_posts.

Добавление обработчика AJAX в functions.php

В файл functions.php вашей темы или плагина добавьте следующий код:

add_action('wp_ajax_wpquery_filter_posts', 'wpquery_filter_posts_callback');
add_action('wp_ajax_nopriv_wpquery_filter_posts', 'wpquery_filter_posts_callback');

function wpquery_filter_posts_callback() {
    $args = [
        'post_type' => 'post',
        'posts_per_page' => 10
    ];

    // Фильтрация по категориям
    if (!empty($_POST['categories'])) {
        $categories = array_map('intval', $_POST['categories']);
        $args['category__in'] = $categories;
    }

    // Фильтрация по цене (мета-поле)
    if (!empty($_POST['price_min']) && !empty($_POST['price_max'])) {
        $args['meta_query'] = [
            [
                'key' => 'price',
                'value' => [(int)$_POST['price_min'], (int)$_POST['price_max']],
                'compare' => 'BETWEEN',
                'type' => 'NUMERIC'
            ]
        ];
    }

    $query = new WP_Query($args);

    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            echo '<div class="post-item">';
            echo '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>';
            echo '<p>Цена: ' . get_post_meta(get_the_ID(), 'price', true) . '</p>';
            echo '</div>';
        }
    } else {
        echo '<p>Посты не найдены.</p>';
    }
    wp_reset_postdata();
    wp_die();
}

Этот обработчик принимает параметры фильтра из AJAX-запроса, формирует аргументы для WP_Query и выводит HTML с результатами.

Пример HTML-формы фильтра и интеграция с AJAX

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

<form id="filter-form">
    <h4>Категории</h4>
    <label><input type="checkbox" name="categories[]" value="5"> Категория 1</label><br>
    <label><input type="checkbox" name="categories[]" value="10"> Категория 2</label><br>
    
    <h4>Цена</h4>
    <label>От: <input type="number" name="price_min" value="1000"></label><br>
    <label>До: <input type="number" name="price_max" value="5000"></label><br>
</form>

<div id="posts-container"></div>

Не забудьте в вашем JS-файле или в functions.php зарегистрировать и локализовать скрипт, чтобы переменная ajaxurl была доступна:

function wpquery_enqueue_scripts() {
    wp_enqueue_script('wpquery-filter', get_template_directory_uri() . '/js/wpquery-filter.js', ['jquery'], null, true);
    wp_localize_script('wpquery-filter', 'ajaxurl', admin_url('admin-ajax.php'));
}
add_action('wp_enqueue_scripts', 'wpquery_enqueue_scripts');

Оптимизация и советы по безопасности

1. Всегда фильтруйте и валидируйте входящие данные из $_POST. В нашем примере мы применили array_map('intval', ...) для категорий и кастинг к (int) для цены.

2. Используйте wp_die() в конце AJAX-обработчика, чтобы корректно завершить выполнение.

3. Для больших баз данных добавьте пагинацию и кеширование результатов, чтобы снизить нагрузку на сервер.

4. При необходимости расширяйте фильтр, добавляя другие таксономии, мета-поля или даже пользовательские поля.

Заключение

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

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

Как создать уникальный REST API endpoint в WordPress: подробное руководство с примерами
01.12.2025
Как удалить дубликаты постов в WordPress: эффективные методы и примеры кода
11.01.2026
Как удалить неактивных пользователей в WordPress через HTML и PHP
14.01.2026
WooCommerce: не отправляются письма о статусах заказов — как исправить
17.05.2026
Как отображать поля ACF в REST API WordPress
24.01.2026