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

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

Почему стоит использовать AJAX-фильтр в WordPress

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

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

Подготовка: регистрация таксономий и кастомных типов записей

Для примера создадим кастомный тип записи product и две таксономии — product_category и product_tag. Если у вас уже есть эти элементы, можно пропустить этот шаг.

function wplessons_register_cpt_and_taxonomies() {
    register_post_type('product', [
        'labels' => [
            'name' => 'Продукты',
            'singular_name' => 'Продукт'
        ],
        'public' => true,
        'has_archive' => true,
        'show_in_rest' => true,
        'supports' => ['title', 'editor', 'thumbnail']
    ]);

    register_taxonomy('product_category', 'product', [
        'labels' => ['name' => 'Категории продуктов'],
        'hierarchical' => true,
        'show_in_rest' => true
    ]);

    register_taxonomy('product_tag', 'product', [
        'labels' => ['name' => 'Теги продуктов'],
        'hierarchical' => false,
        'show_in_rest' => true
    ]);
}
add_action('init', 'wplessons_register_cpt_and_taxonomies');

Этот код регистрирует все необходимые элементы для дальнейшей работы фильтра.

Шаг 1. Вывод фильтра на фронтенде

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

function wplessons_render_filter_form() {
    $categories = get_terms(['taxonomy' => 'product_category', 'hide_empty' => true]);
    $tags = get_terms(['taxonomy' => 'product_tag', 'hide_empty' => true]);
    ?>
    <form id="wplessons-filter-form">
        <h3>Категории</h3>
        <div class="filter-group">
            <?php foreach ($categories as $cat): ?>
                <label>
                    <input type="checkbox" name="product_category[]" value="<?php echo esc_attr($cat->slug); ?>"> <?php echo esc_html($cat->name); ?>
                </label><br>
            <?php endforeach; ?>
        </div>

        <h3>Теги</h3>
        <div class="filter-group">
            <?php foreach ($tags as $tag): ?>
                <label>
                    <input type="checkbox" name="product_tag[]" value="<?php echo esc_attr($tag->slug); ?>"> <?php echo esc_html($tag->name); ?>
                </label><br>
            <?php endforeach; ?>
        </div>

        <button type="submit">Фильтровать</button>
    </form>
    <div id="wplessons-filter-results"></div>
    <?php
}

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

Шаг 2. AJAX обработчик в functions.php

Добавим обработчик AJAX-запросов для фильтрации записей на основе выбранных таксономий.

function wplessons_ajax_filter_products() {
    // Проверка nonce может быть добавлена для безопасности

    $categories = isset($_POST['product_category']) ? array_map('sanitize_text_field', $_POST['product_category']) : [];
    $tags = isset($_POST['product_tag']) ? array_map('sanitize_text_field', $_POST['product_tag']) : [];

    $tax_query = ['relation' => 'AND'];

    if (!empty($categories)) {
        $tax_query[] = [
            'taxonomy' => 'product_category',
            'field' => 'slug',
            'terms' => $categories,
            'operator' => 'IN'
        ];
    }

    if (!empty($tags)) {
        $tax_query[] = [
            'taxonomy' => 'product_tag',
            'field' => 'slug',
            'terms' => $tags,
            'operator' => 'IN'
        ];
    }

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

    $query = new WP_Query($args);

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

Обработчик принимает массивы выбранных категорий и тегов, строит запрос WP_Query с параметром tax_query и возвращает HTML-список результатов.

Шаг 3. JavaScript для отправки AJAX-запросов

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

function wplessons_enqueue_scripts() {
    wp_enqueue_script('wplessons-ajax-filter', get_template_directory_uri() . '/js/ajax-filter.js', ['jquery'], null, true);
    wp_localize_script('wplessons-ajax-filter', 'wplessons_ajax', [
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('wplessons_filter_nonce')
    ]);
}
add_action('wp_enqueue_scripts', 'wplessons_enqueue_scripts');

Файл ajax-filter.js:

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

        var data = $(this).serialize();
        data += '&action=wplessons_filter_products';

        $.post(wplessons_ajax.ajax_url, data, function(response) {
            $('#wplessons-filter-results').html(response);
        });
    });
});

Советы по оптимизации и расширению фильтра

Добавление проверки nonce для безопасности

Чтобы защитить AJAX-запросы от CSRF, используйте nonce:

// В JS отправляем nonce
var data = $(this).serialize();
data += '&action=wplessons_filter_products&nonce=' + wplessons_ajax.nonce;

// В PHP проверяем
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'wplessons_filter_nonce')) {
    wp_die('Ошибка безопасности');
}

Добавление пагинации и сортировки

Для расширения фильтра можно добавить параметры сортировки и пагинации. Передавайте номер страницы и сортировку через AJAX, а в WP_Query добавляйте 'paged' и 'orderby'.

Интеграция с плагином Clearfy Pro для оптимизации

Если вы используете Clearfy Pro, можно дополнительно оптимизировать работу AJAX-запросов и отключить ненужные скрипты на странице с фильтром, что ускорит загрузку.

Вывод

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

Оптимизация кэширования WooCommerce для ускорения интернет-магазина
22.04.2026
Как изменить размер и форму аватара в WordPress с примерами кода
26.01.2026
Как создать меню в WordPress с помощью хука wp_nav_menu
01.11.2025
Как избежать проблем при использовании PHP 8 в WordPress
15.03.2026
Автоматическое удаление товаров из заказов WooCommerce после отмены или возврата
28.05.2026