Для сайтов на 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. Используя приведённые примеры, вы сможете быстро внедрить удобный фильтр для любых типов записей и таксономий. При необходимости расширяйте функционал, добавляя пагинацию, сортировки и интеграцию с полезными плагинами.