Для интернет-магазинов и каталогов на WordPress важна удобная и быстрая фильтрация товаров. Стандартная фильтрация часто требует перезагрузки страницы, что ухудшает пользовательский опыт. В этой статье разберём, как добавить AJAX фильтрацию товаров, чтобы результаты обновлялись динамически без перезагрузки, используя кастомный код и популярные плагины.
Почему AJAX фильтрация важна для WordPress сайтов
AJAX (Asynchronous JavaScript and XML) позволяет загружать данные с сервера асинхронно, не перезагружая всю страницу. Это сокращает время ожидания и делает интерфейс более отзывчивым. Для магазинов и каталогов это значит, что пользователи быстрее находят нужные товары, повышается конверсия и удобство.
В WordPress AJAX фильтрация часто реализуется для произвольных типов постов и WooCommerce товаров. Можно использовать готовые плагины, но иногда требуется кастомное решение для точной настройки и оптимизации.
Пример AJAX фильтрации для произвольного типа постов в WordPress
Рассмотрим пример, как реализовать AJAX фильтрацию для кастомного типа постов "product" с таксономией "product_cat" и мета-полем "price".
Шаг 1. Подключаем скрипт AJAX
Добавим в functions.php темы следующий код для подключения JS и передачи ajax_url:
function wpsetup_enqueue_scripts() {
wp_enqueue_script('wpsetup-ajax-filter', get_template_directory_uri() . '/js/ajax-filter.js', array('jquery'), null, true);
wp_localize_script('wpsetup-ajax-filter', 'wpsetup_ajax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpsetup_filter_nonce')
));
}
add_action('wp_enqueue_scripts', 'wpsetup_enqueue_scripts');Этот скрипт позволит нам отправлять AJAX запросы к WordPress.
Шаг 2. Создаем JS для обработки фильтра
Создайте файл js/ajax-filter.js в вашей теме с таким содержанием:
jQuery(document).ready(function($) {
$('#wpsetup-filter-form').on('change', 'select, input', function() {
var data = $('#wpsetup-filter-form').serialize();
$.ajax({
url: wpsetup_ajax.ajax_url,
type: 'POST',
data: {
action: 'wpsetup_filter_posts',
nonce: wpsetup_ajax.nonce,
filter: data
},
success: function(response) {
if(response.success) {
$('#wpsetup-filter-results').html(response.data);
} else {
$('#wpsetup-filter-results').html('Ошибка загрузки данных');
}
},
error: function() {
$('#wpsetup-filter-results').html('Ошибка AJAX запроса');
}
});
});
});Этот скрипт слушает изменения в форме фильтра и отправляет запрос на сервер.
Шаг 3. Создаем форму фильтрации в шаблоне
В нужном шаблоне выведите форму и контейнер для результатов:
<form id="wpsetup-filter-form">
<label>Категория:</label>
<select name="product_cat">
<option value="">Все</option>
<?php
$terms = get_terms('product_cat', array('hide_empty' => true));
foreach($terms as $term) {
echo '<option value="' . esc_attr($term->slug) . '">' . esc_html($term->name) . '</option>';
}
?>
</select>
<label>Максимальная цена:</label>
<input type="number" name="max_price" min="0" step="1" />
</form>
<div id="wpsetup-filter-results"><!-- Здесь будут выводиться результаты --></div>Шаг 4. Обработка AJAX запроса в PHP
Добавьте в functions.php обработчик AJAX:
function wpsetup_ajax_filter_posts() {
check_ajax_referer('wpsetup_filter_nonce', 'nonce');
parse_str($_POST['filter'], $filter);
$tax_query = array();
if(!empty($filter['product_cat'])) {
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => sanitize_text_field($filter['product_cat'])
);
}
$meta_query = array();
if(!empty($filter['max_price'])) {
$meta_query[] = array(
'key' => 'price',
'value' => intval($filter['max_price']),
'type' => 'NUMERIC',
'compare' => '<='
);
}
$args = array(
'post_type' => 'product',
'posts_per_page' => 10,
'tax_query' => $tax_query,
'meta_query' => $meta_query
);
$query = new WP_Query($args);
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();
$html = ob_get_clean();
wp_send_json_success($html);
} else {
wp_send_json_success('<p>Товары не найдены</p>');
}
wp_die();
}
add_action('wp_ajax_wpsetup_filter_posts', 'wpsetup_ajax_filter_posts');
add_action('wp_ajax_nopriv_wpsetup_filter_posts', 'wpsetup_ajax_filter_posts');Использование плагинов для AJAX фильтрации в WordPress
Если вы не хотите писать код, можно использовать популярные плагины, которые поддерживают AJAX фильтрацию и легко настраиваются:
- FacetWP – мощный плагин с множеством вариантов фильтрации, работает с любыми типами постов и таксономиями, поддерживает AJAX.
- WOOF – WooCommerce Products Filter – бесплатный и премиум плагин для фильтрации товаров WooCommerce с AJAX обновлением.
- Filter Everything – универсальный плагин фильтрации контента с поддержкой AJAX, легко настраивается.
Для интеграции с этими плагинами часто не требуется писать код, но если нужно, можно использовать их API и хуки для расширения возможностей.
Оптимизация AJAX фильтрации: кеширование и производительность
AJAX фильтрация может создавать высокую нагрузку на сервер, особенно при большом количестве товаров. Чтобы сохранить производительность, рекомендуется:
- Использовать WP Object Cache и плагины кеширования, например, Clearfy Pro, который оптимизирует работу WordPress и кеш.
- Ограничить количество выводимых результатов и использовать пагинацию.
- Минимизировать количество запросов к базе данных, используя транзиенты для кеширования результатов.
Дополнительные советы по кастомизации фильтрации
Вы можете расширить фильтр, добавив другие поля, например, сортировку по цене, рейтингу или по дате добавления. Для этого в форме добавьте соответствующие элементы, а в обработчике AJAX расширьте параметры WP_Query.
Также полезно добавить индикаторы загрузки и сообщения об ошибках в JS, чтобы пользователь понимал, что происходит.
Вот пример, как добавить сортировку по цене:
<label>Сортировать по цене:</label>
<select name="orderby">
<option value="date">По дате</option>
<option value="price_asc">По возрастанию цены</option>
<option value="price_desc">По убыванию цены</option>
</select>А в PHP добавьте обработку параметра:
if(!empty($filter['orderby'])) {
switch($filter['orderby']) {
case 'price_asc':
$args['orderby'] = 'meta_value_num';
$args['meta_key'] = 'price';
$args['order'] = 'ASC';
break;
case 'price_desc':
$args['orderby'] = 'meta_value_num';
$args['meta_key'] = 'price';
$args['order'] = 'DESC';
break;
default:
$args['orderby'] = 'date';
$args['order'] = 'DESC';
}
}