Как создать динамический фильтр записей в 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.

Как массово удалить мета-поля у записей в WordPress по определённым условиям
01.01.2026
Как добавить поддержку WebP в WordPress без плагинов
25.02.2026
Автоматическое удаление товаров в WooCommerce при отсутствии на складе
18.04.2026
Как создать и настроить круговое меню в WordPress без плагинов
04.01.2026
Как создать динамический фильтр записей в WordPress без плагинов
28.12.2025