В интернет-магазинах и каталогах продуктов на WordPress частая задача — это организовать удобный и многоуровневый фильтр товаров по различным параметрам. Многие идут по простому пути и ставят тяжеловесные плагины-фильтры, которые сильно нагружают сайт. В этой статье мы подробно разберем, как создать собственный многоуровневый фильтр продуктов на WordPress без плагинов, используя кастомные таксономии, AJAX и оптимизированный код.
Почему стоит создавать фильтр продуктов самостоятельно
Готовые плагины часто имеют массу лишних функций, замедляют сайт и создают сложности с кастомизацией. Самодельный фильтр:
- Легкий и быстрый, загружается только нужный функционал
- Полностью контролируемый код, который можно адаптировать под свои нужды
- Можно интегрировать с любыми типами записей и таксономиями
- Избегаете конфликтов с другими плагинами
Для примера возьмем тип записи product, а для фильтрации используем две кастомные таксономии — product_cat (категории) и product_brand (бренды).
Создаем кастомные таксономии для фильтрации
Для начала зарегистрируем таксономии через хук init. Добавим следующий код в файл functions.php вашей темы или в отдельный плагин:
function wppremium_register_product_taxonomies() {
register_taxonomy('product_cat', 'product', array(
'hierarchical' => true,
'label' => 'Категории продуктов',
'show_ui' => true,
'query_var' => true,
'rewrite' => array('slug' => 'product_cat'),
));
register_taxonomy('product_brand', 'product', array(
'hierarchical' => false,
'label' => 'Бренды',
'show_ui' => true,
'query_var' => true,
'rewrite' => array('slug' => 'product_brand'),
));
}
add_action('init', 'wppremium_register_product_taxonomies');
Теперь у продуктов появятся новые поля для выбора категории и бренда. Можно заполнить их через админку.
Создаем форму фильтра с многоуровневым выбором
Далее сделаем сам HTML формы фильтра, которая будет выводить все доступные категории и бренды. Вставим код в нужный шаблон (например, archive-product.php):
<form id="wppremium-product-filter" method="GET" action="<?php echo esc_url(home_url('/products/')); ?>">
<h3>Фильтр по категориям</h3>
<ul>
<?php
$categories = get_terms(array(
'taxonomy' => 'product_cat',
'hide_empty' => false,
'parent' => 0
));
foreach ($categories as $cat) {
echo '<li><label><input type="checkbox" name="product_cat[]" value="' . esc_attr($cat->slug) . '"> ' . esc_html($cat->name) . '</label>';
$child_cats = get_terms(array('taxonomy' => 'product_cat', 'parent' => $cat->term_id, 'hide_empty' => false));
if ($child_cats) {
echo '<ul>';
foreach ($child_cats as $child) {
echo '<li><label><input type="checkbox" name="product_cat[]" value="' . esc_attr($child->slug) . '"> ' . esc_html($child->name) . '</label></li>';
}
echo '</ul>';
}
echo '</li>';
}
?>
</ul>
<h3>Фильтр по брендам</h3>
<ul>
<?php
$brands = get_terms(array('taxonomy' => 'product_brand', 'hide_empty' => false));
foreach ($brands as $brand) {
echo '<li><label><input type="checkbox" name="product_brand[]" value="' . esc_attr($brand->slug) . '"> ' . esc_html($brand->name) . '</label></li>';
}
?>
</ul>
<button type="submit">Применить фильтр</button>
</form>
Здесь мы выводим категории с вложенными подкатегориями и список брендов. Пользователь может выбрать несколько вариантов.
Обработка фильтра и вывод результатов с WP_Query
При отправке формы нам нужно обработать параметры и вывести отфильтрованные продукты. В шаблоне архива продуктов добавьте следующий PHP-код:
$tax_query = array('relation' => 'AND');
if (!empty($_GET['product_cat'])) {
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array_map('sanitize_text_field', $_GET['product_cat']),
'operator' => 'IN'
);
}
if (!empty($_GET['product_brand'])) {
$tax_query[] = array(
'taxonomy' => 'product_brand',
'field' => 'slug',
'terms' => array_map('sanitize_text_field', $_GET['product_brand']),
'operator' => 'IN'
);
}
$args = array(
'post_type' => 'product',
'posts_per_page' => 12,
'tax_query' => $tax_query
);
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<div class="wppremium-products-grid">';
while ($query->have_posts()) {
$query->the_post();
echo '<div class="product-item">';
the_title('<h4>', '</h4>');
// Добавьте вывод миниатюры и цены по необходимости
echo '</div>';
}
echo '</div>';
} else {
echo '<p>Товары не найдены</p>';
}
wp_reset_postdata();
Так мы выводим товары, соответствующие выбранным категориям и брендам.
Добавляем AJAX для динамического обновления результатов
Чтобы фильтр работал без перезагрузки страницы, подключим AJAX. Для этого сделаем JavaScript и обработчик в PHP.
JavaScript для отправки AJAX-запроса
jQuery(document).ready(function($) {
$('#wppremium-product-filter input[type=checkbox]').on('change', function() {
var data = $('#wppremium-product-filter').serialize();
$.ajax({
url: wppremium_ajax_object.ajax_url,
type: 'GET',
data: data + '&action=wppremium_filter_products',
beforeSend: function() {
$('.wppremium-products-grid').fadeTo(200, 0.5);
},
success: function(response) {
$('.wppremium-products-grid').html(response).fadeTo(200, 1);
},
error: function() {
alert('Ошибка при загрузке товаров');
}
});
});
});
Эту часть нужно подключить в футере, предварительно зарегистрировав скрипт и передав в него URL AJAX:
function wppremium_enqueue_scripts() {
wp_enqueue_script('wppremium-filter', get_template_directory_uri() . '/js/wppremium-filter.js', array('jquery'), null, true);
wp_localize_script('wppremium-filter', 'wppremium_ajax_object', array(
'ajax_url' => admin_url('admin-ajax.php')
));
}
add_action('wp_enqueue_scripts', 'wppremium_enqueue_scripts');
PHP-обработчик AJAX-запроса
function wppremium_ajax_filter_products() {
$tax_query = array('relation' => 'AND');
if (!empty($_GET['product_cat'])) {
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array_map('sanitize_text_field', $_GET['product_cat']),
'operator' => 'IN'
);
}
if (!empty($_GET['product_brand'])) {
$tax_query[] = array(
'taxonomy' => 'product_brand',
'field' => 'slug',
'terms' => array_map('sanitize_text_field', $_GET['product_brand']),
'operator' => 'IN'
);
}
$args = array(
'post_type' => 'product',
'posts_per_page' => 12,
'tax_query' => $tax_query
);
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
echo '<div class="product-item">';
the_title('<h4>', '</h4>');
echo '</div>';
}
} else {
echo '<p>Товары не найдены</p>';
}
wp_reset_postdata();
wp_die();
}
add_action('wp_ajax_wppremium_filter_products', 'wppremium_ajax_filter_products');
add_action('wp_ajax_nopriv_wppremium_filter_products', 'wppremium_ajax_filter_products');
Практические советы и оптимизация фильтра
Чтобы фильтр работал быстро и правильно, стоит учесть следующие моменты:
- Используйте индексы для таксономий в базе данных — WordPress делает это по умолчанию, но не стоит создавать лишние кастомные таблицы без необходимости.
- Ограничьте количество одновременно выводимых результатов и используйте пагинацию.
- Кэшируйте результаты при высокой нагрузке, например, с помощью Object Cache.
- Для сложных фильтров с множеством параметров применяйте
WP_Meta_Queryи оптимизируйте запросы. - Если используете плагин Clearfy Pro, он поможет отключить ненужный функционал и ускорить работу фильтра.
Заключение
Создание многоуровневого фильтра продуктов в WordPress без плагинов — вполне выполнимая задача. Такой подход даст вам полный контроль над функционалом и позволит оптимизировать работу сайта. Используйте кастомные таксономии, WP_Query с таксономическим фильтром и AJAX для динамического обновления. В результате вы получите легкий, быстрый и удобный интерфейс фильтрации товаров.
Если хотите расширить функционал фильтра, рекомендуем обратить внимание на плагины из каталога WPSHOP, например, Expert Review для отзывов или ABC Pagination для удобной постраничной навигации.