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

|

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

Понимание задачи: что такое комплексный фильтр записей WordPress

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

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

Использование WP_Query для нескольких условий: практический пример

Рассмотрим пример, когда нам нужно вывести записи, которые находятся в категории с ID 10, имеют мета-поле price больше 1000, и опубликованы после 1 января 2023 года.

Основной инструмент — класс WP_Query с передачей массива параметров.

$args = [
    'post_type'      => 'post',
    'posts_per_page' => 10,
    'category__in'   => [10],
    'meta_query'     => [
        [
            'key'     => 'price',
            'value'   => 1000,
            'compare' => '>',
            'type'    => 'NUMERIC',
        ],
    ],
    'date_query'     => [
        [
            'after'     => '2023-01-01',
            'inclusive' => true,
        ],
    ],
];
$query = new WP_Query($args);

Далее выводим записи в цикле:

if ($query->have_posts()) {
    while ($query->have_posts()) {
        $query->the_post();
        echo '<h2>' . get_the_title() . '</h2>';
        echo '<div>' . get_the_excerpt() . '</div>';
    }
    wp_reset_postdata();
} else {
    echo 'Записи не найдены';
}

Создание формы фильтра с несколькими полями

Чтобы фильтр был интерактивным, нужна форма с несколькими полями, например:

Пример HTML-формы:

<form method="GET" id="wppremium-filter" action="">
    <select name="category">
        <option value="">Выберите категорию</option>
        <?php
        $categories = get_categories();
        foreach ($categories as $cat) {
            echo '<option value="' . $cat->term_id . '"' . (isset($_GET['category']) && $_GET['category'] == $cat->term_id ? ' selected' : '') . '>' . $cat->name . '</option>';
        }
        ?>
    </select>

    <input type="number" name="price_min" placeholder="Минимальная цена" value="<?php echo esc_attr($_GET['price_min'] ?? ''); ?>" />
    <input type="number" name="price_max" placeholder="Максимальная цена" value="<?php echo esc_attr($_GET['price_max'] ?? ''); ?>" />

    <input type="date" name="date_from" value="<?php echo esc_attr($_GET['date_from'] ?? ''); ?>" />
    <input type="date" name="date_to" value="<?php echo esc_attr($_GET['date_to'] ?? ''); ?>" />

    <button type="submit">Фильтровать</button>
</form>

Обработка параметров формы и создание запроса WP_Query

В PHP нужно собрать параметры GET-запроса, сформировать массив $args для WP_Query, учитывая все переданные условия.

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

    if (!empty($_GET['category'])) {
        $args['category__in'] = [(int) $_GET['category']];
    }

    if (!empty($_GET['price_min']) || !empty($_GET['price_max'])) {
        $price_filter = ['key' => 'price', 'type' => 'NUMERIC'];
        if (!empty($_GET['price_min'])) {
            $price_filter['value'][] = (int) $_GET['price_min'];
            $price_filter['compare'] = '>=';
        }
        if (!empty($_GET['price_max'])) {
            if (isset($price_filter['value'])) {
                $price_filter['value'][] = (int) $_GET['price_max'];
                $price_filter['compare'] = 'BETWEEN';
            } else {
                $price_filter['value'] = (int) $_GET['price_max'];
                $price_filter['compare'] = '<=';
            }
        }
        $args['meta_query'][] = $price_filter;
    }

    if (!empty($_GET['date_from']) || !empty($_GET['date_to'])) {
        $date_filter = [];
        if (!empty($_GET['date_from'])) {
            $date_filter['after'] = sanitize_text_field($_GET['date_from']);
        }
        if (!empty($_GET['date_to'])) {
            $date_filter['before'] = sanitize_text_field($_GET['date_to']);
        }
        $date_filter['inclusive'] = true;
        $args['date_query'][] = $date_filter;
    }

    // Если meta_query пустой, убрать его чтобы не мешать запросу
    if (empty($args['meta_query'])) {
        unset($args['meta_query']);
    }

    // Если date_query пустой, убрать его
    if (empty($args['date_query'])) {
        unset($args['date_query']);
    }

    return $args;
}

// Использование
$args = wppremium_build_filter_query();
$query = new WP_Query($args);

Добавление AJAX для обновления результатов без перезагрузки

Чтобы улучшить UX, можно сделать так, чтобы по изменению параметров фильтра страница не перезагружалась, а результаты обновлялись динамически.

Общий алгоритм:

Пример jQuery-кода для отправки AJAX:

jQuery(document).ready(function($) {
    $('#wppremium-filter').on('submit', function(e) {
        e.preventDefault();
        var data = $(this).serialize();
        $.ajax({
            url: wppremium_ajax_object.ajax_url,
            method: 'POST',
            data: {
                action: 'wppremium_filter_posts',
                filter: data
            },
            success: function(response) {
                $('#wppremium-results').html(response);
            }
        });
    });
});

Пример обработки AJAX в functions.php:

add_action('wp_ajax_wppremium_filter_posts', 'wppremium_ajax_filter_posts');
add_action('wp_ajax_nopriv_wppremium_filter_posts', 'wppremium_ajax_filter_posts');
function wppremium_ajax_filter_posts() {
    parse_str($_POST['filter'], $filter_params);
    $_GET = $filter_params; // для использования функции построения запроса

    $args = wppremium_build_filter_query();
    $query = new WP_Query($args);

    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            echo '<h2>' . get_the_title() . '</h2>';
            echo '<div>' . get_the_excerpt() . '</div>';
        }
    } else {
        echo 'Результаты не найдены';
    }
    wp_die();
}

Использование плагинов для расширения возможностей фильтра

Если хочется получить еще больше функционала с минимальными усилиями, можно обратить внимание на плагины:

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

Оптимизация запросов и советы по производительности

При сложных фильтрах нужно помнить, что WP_Query с большим количеством условий может грузить сервер. Советы:

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

Как удалить пользовательские данные при удалённой регистрации WordPress
21.02.2026
Как избежать проблем с кэшированием в WordPress: практические советы
09.12.2025
Как автоматизировать удаление спама в комментариях WordPress
05.02.2026
Как создать комплексный фильтр для записей WordPress с несколькими условиями
27.02.2026
Как оптимизировать загрузку картинок в WordPress для ускорения сайта
18.11.2025
×
-15%
на премиум плагин
My Popup

Повысьте конверсию!

Получить скидку »