Фильтрация товаров — одна из ключевых функций интернет-магазина на WooCommerce. Часто владельцы магазинов используют готовые плагины для фильтрации, однако они могут замедлять сайт и перегружать админку. В этой статье мы подробно разберем, как создать адаптивный и легковесный фильтр товаров на WooCommerce без использования сторонних плагинов.
Почему стоит создавать собственный фильтр без плагинов
Готовые плагины, например, FacetWP, WOOF или Product Filter, действительно удобны, но имеют ряд минусов:
- Увеличение нагрузки на сервер из-за дополнительных запросов;
- Нередко плагины конфликтуют с темой или другими расширениями;
- Ограниченные возможности кастомизации под конкретный дизайн и бизнес-логику;
- Платные версии могут быть дорогими.
Создавая свой фильтр, вы получаете полный контроль над функционалом, минимизируете нагрузку и лучше интегрируете фильтрацию в дизайн.
Основы работы с WP_Query и параметрами фильтрации
WooCommerce использует класс WC_Query, основанный на WP_Query. Для фильтрации товаров нужно модифицировать параметры запроса, основываясь на выбранных пользователем критериях.
К основным критериям фильтрации относятся:
- Категории товаров;
- Атрибуты (цвет, размер, бренд и др.);
- Цена;
- Наличие на складе;
- Рейтинг и другие метаданные.
Чтобы отфильтровать товары без плагинов, нам нужно добавить обработку GET-параметров в запрос.
Пример фильтрации по категории и атрибуту
Допустим, у нас есть атрибут pa_color и категория товара. В файле шаблона архива товаров или в функции фильтрации запроса добавим:
add_action('pre_get_posts', 'wp0_filter_woocommerce_products');
function wp0_filter_woocommerce_products($query) {
if (is_admin() || !$query->is_main_query() || !is_post_type_archive('product')) {
return;
}
$tax_query = array();
if (!empty($_GET['product_cat'])) {
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => sanitize_text_field($_GET['product_cat']),
);
}
if (!empty($_GET['pa_color'])) {
$tax_query[] = array(
'taxonomy' => 'pa_color',
'field' => 'slug',
'terms' => sanitize_text_field($_GET['pa_color']),
);
}
if ($tax_query) {
$query->set('tax_query', $tax_query);
}
}Этот код добавляет фильтрацию товаров по категории и цвету, если соответствующие параметры есть в URL.
Создание фронтенд-формы фильтрации
Чтобы пользователи могли выбирать фильтры, нужно вывести HTML-форму с нужными полями. Пример формы фильтрации по категориям и цвету:
<form method="get" action="" id="wp0-product-filter">
<label for="product_cat">Категория:</label>
<select name="product_cat" id="product_cat">
<option value="">Все категории</option>
<?php
$categories = get_terms('product_cat', array('hide_empty' => true));
foreach ($categories as $category) {
$selected = (isset($_GET['product_cat']) && $_GET['product_cat'] === $category->slug) ? 'selected' : '';
echo "<option value=\"{$category->slug}\" $selected>{$category->name}</option>";
}
?>
</select>
<label for="pa_color">Цвет:</label>
<select name="pa_color" id="pa_color">
<option value="">Все цвета</option>
<?php
$colors = get_terms('pa_color', array('hide_empty' => true));
foreach ($colors as $color) {
$selected = (isset($_GET['pa_color']) && $_GET['pa_color'] === $color->slug) ? 'selected' : '';
echo "<option value=\"{$color->slug}\" $selected>{$color->name}</option>";
}
?>
</select>
<button type="submit">Фильтровать</button>
</form>Форма отправляет выбранные параметры методом GET, которые мы обрабатываем в функции фильтрации.
Добавление фильтра по цене с использованием мета-запросов
Фильтрация по цене — одна из самых популярных задач. WooCommerce хранит цену в метаполе _price. Для фильтрации по диапазону стоимости используйте параметр meta_query.
add_action('pre_get_posts', 'wp0_filter_woocommerce_price');
function wp0_filter_woocommerce_price($query) {
if (is_admin() || !$query->is_main_query() || !is_post_type_archive('product')) {
return;
}
$meta_query = $query->get('meta_query');
if (!is_array($meta_query)) {
$meta_query = array();
}
$price_min = isset($_GET['price_min']) ? floatval($_GET['price_min']) : 0;
$price_max = isset($_GET['price_max']) ? floatval($_GET['price_max']) : 0;
if ($price_min > 0 || $price_max > 0) {
$price_filter = array('key' => '_price', 'type' => 'NUMERIC');
if ($price_min > 0) {
$price_filter['value'][] = $price_min;
$price_filter['compare'] = '>=';
}
if ($price_max > 0) {
$price_filter['value'][] = $price_max;
$price_filter['compare'] = $price_min > 0 ? 'BETWEEN' : '<=';
}
if ($price_min > 0 && $price_max > 0) {
$price_filter['value'] = array($price_min, $price_max);
$price_filter['compare'] = 'BETWEEN';
}
$meta_query[] = $price_filter;
}
$query->set('meta_query', $meta_query);
}Добавим к форме фильтра поля для минимальной и максимальной цены:
<label for="price_min">Цена от:</label>
<input type="number" name="price_min" id="price_min" value="<?php echo isset($_GET['price_min']) ? esc_attr($_GET['price_min']) : ''; ?>" step="0.01" min="0" />
<label for="price_max">Цена до:</label>
<input type="number" name="price_max" id="price_max" value="<?php echo isset($_GET['price_max']) ? esc_attr($_GET['price_max']) : ''; ?>" step="0.01" min="0" />Оптимизация и кеширование фильтрации
Чтобы фильтр работал быстро даже на больших каталогах, важно оптимизировать запросы и использовать кеширование. Рекомендуется:
- Использовать индексы в базе данных для метаполей и таксономий;
- Кешировать результаты запроса с помощью Transients API;
- Минимизировать количество запросов и не делать тяжелые JOIN’ы;
- Ограничивать количество одновременно выбранных фильтров.
Для кеширования можно добавить в функцию фильтрации проверку и сохранение результата так:
function wp0_get_filtered_products() {
$cache_key = 'wp0_filtered_products_' . md5(serialize($_GET));
$cached = get_transient($cache_key);
if ($cached !== false) {
return $cached;
}
$args = array(
'post_type' => 'product',
'posts_per_page' => 12,
// параметры фильтрации из $_GET
);
$query = new WP_Query($args);
set_transient($cache_key, $query->posts, 3600); // кеш на 1 час
return $query->posts;
}
Советы по улучшению UX фильтра
Чтобы пользователи с удовольствием использовали фильтр, нужно сделать его удобным:
- Добавить кнопку сброса всех фильтров;
- Использовать AJAX для обновления списка без перезагрузки страницы (пример с использованием jQuery и
admin-ajax.phpможно реализовать отдельно); - Показывать количество товаров рядом с каждым фильтром;
- Делать фильтры интуитивно понятными и компактными.
Использование плагинов WPGPT и Clearfy Pro для расширения фильтрации
Для тех, кто хочет упростить процесс создания фильтров и повысить производительность сайта, можно рекомендовать плагины из экосистемы WPGPT и Clearfy Pro.
WPGPT помогает создавать динамические фильтры на основе искусственного интеллекта для улучшения поиска товаров, а Clearfy Pro оптимизирует работу сайта и устраняет избыточные запросы, что положительно сказывается на скорости загрузки страниц с фильтрами.
Использование этих инструментов совместно с собственными решениями по фильтрации позволит получить более мощный и быстрый функционал.