Диагностика задачи: зачем нужен кастомный фильтр по атрибутам
Стандартный виджет фильтрации WooCommerce позволяет пользователям выбирать товары по атрибутам, например цвету или размеру. Однако его функционал ограничен: нельзя гибко настроить вывод, добавить AJAX-подгрузку или вывести фильтр в нестандартном месте. В результате пользователи не всегда могут быстро найти нужный товар, а разработчики ищут способ добавить фильтр без установки дополнительных плагинов, чтобы не нагружать сайт.
Пошаговое решение: создание кастомного фильтра по атрибутам
1. Получение атрибутов и значений для фильтра
Для начала нужно получить список атрибутов товара и их термины (значения). В WooCommerce атрибуты хранятся как таксономии с префиксом pa_. Например, атрибут цвет — это таксономия pa_color. Ниже пример кода, который по атрибуту выводит список терминов:
function get_attribute_terms_list($attribute_slug) {
$terms = get_terms(array(
'taxonomy' => 'pa_' . $attribute_slug,
'hide_empty' => true,
));
return $terms;
}2. Вывод фильтра с чекбоксами в произвольном месте
Создадим функцию вывода фильтра с чекбоксами, которая будет принимать атрибут и формировать ссылку с параметрами фильтрации:
function display_attribute_filter($attribute_slug) {
$terms = get_attribute_terms_list($attribute_slug);
if(empty($terms)) return;
$current_values = isset($_GET['filter_' . $attribute_slug]) ? explode(',', sanitize_text_field($_GET['filter_' . $attribute_slug])) : array();
echo '<form method="GET" id="filter_' . esc_attr($attribute_slug) . '">';
foreach($terms as $term) {
$checked = in_array($term->slug, $current_values) ? 'checked' : '';
echo '<label><input type="checkbox" name="filter_' . esc_attr($attribute_slug) . '[]" value="' . esc_attr($term->slug) . '" ' . $checked . ' /> ' . esc_html($term->name) . '</label><br/>';
}
echo '<button type="submit">Применить</button>';
echo '</form>';
}3. Модификация основного запроса WooCommerce для фильтрации товаров
Чтобы фильтр работал, нужно перехватить запрос и добавить параметры таксономий. Используем хук pre_get_posts:
add_action('pre_get_posts', function($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
if (is_shop() || is_product_taxonomy()) {
$tax_query = array();
foreach($_GET as $key => $value) {
if(strpos($key, 'filter_') === 0 && !empty($value)) {
$attribute = str_replace('filter_', '', $key);
$terms = array_map('sanitize_text_field', (array)$value);
$tax_query[] = array(
'taxonomy' => 'pa_' . $attribute,
'field' => 'slug',
'terms' => $terms,
'operator' => 'IN'
);
}
}
if(!empty($tax_query)) {
if(count($tax_query) > 1) {
$tax_query['relation'] = 'AND';
}
$query->set('tax_query', $tax_query);
}
}
});Проверка результата после внедрения
- Откройте страницу магазина (shop) на сайте.
- Вызовите функцию
display_attribute_filter('color')в шаблоне, например в sidebar.php или через хуки. - Выберите один или несколько атрибутов и нажмите «Применить».
- Проверьте, что список товаров обновился и отображаются только товары с выбранными атрибутами.
- Проверьте, что URL содержит параметры
filter_color=red,blueи фильтрация работает при прямом переходе.
Частые ошибки и как их исправить
- Ничего не фильтруется при выборе чекбоксов: проверьте правильность префиксов таксономий (
pa_) и что в URL действительно передаются параметрыfilter_. - Отсутствие товаров при фильтрации: возможно конфликт с другими плагинами, которые модифицируют запрос. Временно отключите плагины и проверьте.
- Форма не отправляет параметры: убедитесь, что метод формы
GET, а имена чекбоксов имеют квадратные скобки[]для массива. - Параметры не распознаются в
pre_get_posts: проверьте, что фильтр применяется только к главному запросу и на страницах магазина или архивов товаров.
Практические советы для безопасности и производительности
- Используйте
sanitize_text_field()для всех входящих данных из$_GET, чтобы избежать XSS и инъекций. - Кэшируйте результаты
get_terms(), если атрибутов много и они редко меняются. - Проверяйте, что фильтр работает только там, где нужно, чтобы избежать нагрузки на другие части сайта.
- Для улучшения UX можно добавить AJAX-подгрузку товаров при изменении фильтра, но это требует дополнительной разработки.
Сравнение способов реализации фильтрации по атрибутам WooCommerce
| Способ | Преимущества | Недостатки |
|---|---|---|
| Стандартный виджет WooCommerce | Прост в использовании, не требует кода | Ограниченная кастомизация, нет AJAX |
| Плагины фильтрации (например, WOOF, FacetWP) | Много функций, AJAX, удобный UI | Нагрузка на сайт, платные версии, возможные конфликты |
| Кастомный фильтр через код (описан в статье) | Точный контроль, нет лишних плагинов, легковесно | Требует знаний PHP, базовый UX без AJAX |