Как создать динамический фильтр записей в WordPress без плагинов

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

Зачем создавать динамический фильтр без плагинов

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

В нашем примере мы создадим фильтр по категориям и кастомному полю (например, «Цена»), который будет работать без перезагрузки страницы с помощью AJAX.

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

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

Создадим функцию wpelement_get_filtered_posts в файле functions.php вашей темы:

function wpelement_get_filtered_posts($category = '', $price_min = 0, $price_max = 0) {
    $meta_query = [];

    if ($price_min > 0 || $price_max > 0) {
        $range = [];
        if ($price_min > 0) $range['>='] = $price_min;
        if ($price_max > 0) $range['<='] = $price_max;

        $meta_query[] = [
            'key' => 'price',
            'value' => [$price_min, $price_max],
            'compare' => 'BETWEEN',
            'type' => 'NUMERIC'
        ];
    }

    $args = [
        'post_type' => 'post',
        'posts_per_page' => 10,
    ];

    if (!empty($category)) {
        $args['category_name'] = sanitize_text_field($category);
    }

    if (!empty($meta_query)) {
        $args['meta_query'] = $meta_query;
    }

    $query = new WP_Query($args);
    return $query;
}

Здесь мы фильтруем записи по категории и по метаполю «price» в диапазоне от $price_min до $price_max.

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

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

Добавьте этот HTML в нужное место шаблона (например, в файл archive.php или отдельный шаблон):

<form id="wpelement-filter-form">
    <label>Категория:</label>
    <select name="category" id="wpelement-category">
        <option value="">Все категории</option>
        <?php
        $categories = get_categories();
        foreach ($categories as $cat) {
            echo '<option value="' . esc_attr($cat->slug) . '">' . esc_html($cat->name) . '</option>';
        }
        ?>
    </select>

    <label>Цена от:</label>
    <input type="number" name="price_min" id="wpelement-price-min" min="0" placeholder="0" />

    <label>до:</label>
    <input type="number" name="price_max" id="wpelement-price-max" min="0" placeholder="10000" />

    <button type="submit">Применить</button>
</form>

<div id="wpelement-filter-results"></div>

Форма содержит выпадающий список с категориями и два поля ввода для ценового диапазона.

AJAX-обработка фильтрации: динамическое обновление результатов

Чтобы не перезагружать страницу, реализуем AJAX-запрос, который будет при отправке формы запрашивать отфильтрованные записи и выводить их в блок #wpelement-filter-results.

Для этого добавим JavaScript в тему (лучше через enqueue):

jQuery(document).ready(function($) {
    $('#wpelement-filter-form').on('submit', function(e) {
        e.preventDefault();

        var data = {
            action: 'wpelement_filter_posts',
            category: $('#wpelement-category').val(),
            price_min: $('#wpelement-price-min').val(),
            price_max: $('#wpelement-price-max').val(),
            nonce: wpelement_ajax.nonce
        };

        $.post(wpelement_ajax.url, data, function(response) {
            if(response.success) {
                $('#wpelement-filter-results').html(response.data);
            } else {
                $('#wpelement-filter-results').html('<p>Ошибка при загрузке данных.</p>');
            }
        });
    });
});

Подключите скрипт и передайте параметры AJAX в functions.php:

function wpelement_enqueue_scripts() {
    wp_enqueue_script('wpelement-filter', get_template_directory_uri() . '/js/wpelement-filter.js', ['jquery'], null, true);
    wp_localize_script('wpelement-filter', 'wpelement_ajax', [
        'url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('wpelement_nonce')
    ]);
}
add_action('wp_enqueue_scripts', 'wpelement_enqueue_scripts');

Обработка AJAX-запроса на сервере

В functions.php добавим обработчик:

function wpelement_ajax_filter_posts() {
    check_ajax_referer('wpelement_nonce', 'nonce');

    $category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : '';
    $price_min = isset($_POST['price_min']) ? intval($_POST['price_min']) : 0;
    $price_max = isset($_POST['price_max']) ? intval($_POST['price_max']) : 0;

    $query = wpelement_get_filtered_posts($category, $price_min, $price_max);

    if ($query->have_posts()) {
        ob_start();
        echo '<ul>';
        while ($query->have_posts()) {
            $query->the_post();
            echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
        }
        echo '</ul>';
        wp_reset_postdata();
        $result = ob_get_clean();
        wp_send_json_success($result);
    } else {
        wp_send_json_success('<p>По вашему запросу ничего не найдено.</p>');
    }
}
add_action('wp_ajax_wpelement_filter_posts', 'wpelement_ajax_filter_posts');
add_action('wp_ajax_nopriv_wpelement_filter_posts', 'wpelement_ajax_filter_posts');

Обработчик получает данные из AJAX, выполняет запрос и возвращает HTML с результатами.

Оптимизация и расширение фильтра

Для реальных проектов можно добавить пагинацию, дополнительные параметры фильтрации (например, по дате или автору), а также кэширование результатов для уменьшения нагрузки.

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

Пример вывода с картинками и описанием

while ($query->have_posts()) {
    $query->the_post();
    echo '<div class="wpelement-post-card">';
    if (has_post_thumbnail()) {
        echo '<div class="wpelement-thumb">' . get_the_post_thumbnail(null, 'thumbnail') . '</div>';
    }
    echo '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>';
    echo '<p>' . get_the_excerpt() . '</p>';
    echo '</div>';
}

Выводы

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

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

Использование WP REST API для автоматизации задач в WordPress
16.03.2026
Как автоматизировать удаление старого контента в WordPress по дате публикации
11.04.2026
Как удалить удалённых пользователей WordPress по дате их последней активности
19.03.2026
Как убрать замедление страниц WooCommerce при большом количестве товаров
22.04.2026
Как решить проблему нерабочих скриптов в WooCommerce после обновления темы
11.05.2026