Диагностика проблемы: почему стандартных фильтров WooCommerce недостаточно
Стандартные виджеты WooCommerce позволяют фильтровать товары по категории, атрибутам, цене и другим параметрам. Однако, если в каталоге используются вложенные категории (подкатегории), пользователи часто хотят видеть фильтрацию именно по подкатегориям, чтобы быстрее находить нужные товары. К сожалению, базовые виджеты WooCommerce показывают категории только первого уровня или все категории без иерархии, что затрудняет навигацию.
Если вы заметили, что ваши пользователи жалуются на неудобство поиска или фильтр не отражает структуру каталога — это сигнал, что нужно добавить кастомную фильтрацию по подкатегориям.
Пошаговое решение: добавление фильтра по подкатегориям с помощью кода
1. Получение подкатегорий текущей категории
Для начала нужно получить подкатегории текущей категории товара. Предположим, что вы находитесь на странице категории, и хотите вывести список подкатегорий именно для нее.
function get_subcategories_of_current_category() {
if (is_product_category()) {
$current_cat = get_queried_object();
$args = array(
'taxonomy' => 'product_cat',
'parent' => $current_cat->term_id,
'hide_empty' => true,
);
return get_terms($args);
}
return array();
}2. Вывод фильтра с чекбоксами для подкатегорий
Создадим функцию, которая выведет список подкатегорий с чекбоксами, позволяющими фильтровать товары на основе выбранных подкатегорий.
function display_subcategory_filter() {
$subcategories = get_subcategories_of_current_category();
if (empty($subcategories)) {
return;
}
// Получаем текущие выбранные фильтры из URL
$selected = isset($_GET['filter_subcats']) ? explode(',', sanitize_text_field($_GET['filter_subcats'])) : array();
echo '<form method="GET" id="subcat-filter-form">';
foreach ($subcategories as $subcategory) {
$checked = in_array($subcategory->slug, $selected) ? 'checked' : '';
echo '<label>';
echo '<input type="checkbox" name="filter_subcats[]" value="' . esc_attr($subcategory->slug) . '" ' . $checked . '/> ';
echo esc_html($subcategory->name);
echo '</label><br/>';
}
echo '<input type="submit" value="Применить фильтр" />';
echo '</form>';
}3. Применение фильтра к основному запросу WooCommerce
Чтобы фильтрация работала, нужно изменить основной WP_Query на странице архива товаров и добавить условие для выбранных подкатегорий.
function filter_products_by_subcategories($query) {
if ( ! is_admin() && $query->is_main_query() && is_product_category() ) {
if (isset($_GET['filter_subcats']) && is_array($_GET['filter_subcats'])) {
$filter_subcats = array_map('sanitize_text_field', $_GET['filter_subcats']);
if (!empty($filter_subcats)) {
$tax_query = (array) $query->get('tax_query');
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $filter_subcats,
'operator' => 'IN',
);
$query->set('tax_query', $tax_query);
}
}
}
}
add_action('pre_get_posts', 'filter_products_by_subcategories');Проверка результата после внедрения
- Перейдите на страницу категории товара, где есть подкатегории.
- Видите форму с чекбоксами подкатегорий.
- Отметьте одну или несколько подкатегорий и нажмите «Применить фильтр».
- Страница перезагрузится, и отобразятся только товары из выбранных подкатегорий.
- Проверьте URL: должен содержать параметр
filter_subcatsс выбранными слагами.
Частые ошибки и как их исправить
- Фильтр не отображается: проверьте, что функция
display_subcategory_filter()вызывается в шаблоне категории, например, вarchive-product.phpили через хукwoocommerce_before_shop_loop. - Фильтрация не работает: убедитесь, что хук
pre_get_postsдобавлен правильно и функция получает главный запрос. Проверьте, что параметр в URL передается и обрабатывается. - Все товары исчезают при фильтрации: возможно, указаны неправильные слаги подкатегорий или подкатегории пустые. Проверьте наличие товаров в выбранных подкатегориях.
- Параметры фильтра не сохраняются при пагинации: добавьте параметр
filter_subcatsв ссылки пагинации через фильтрwoocommerce_pagination_argsили перепишите логику пагинации.
Практические советы по производительности и безопасности
- Старайтесь не выводить слишком много подкатегорий с чекбоксами — если их более 20, рассмотрите использование AJAX-подгрузки или поискового поля.
- Используйте
sanitize_text_fieldи другие функции очистки данных для безопасности при обработке GET-параметров. - Кэшируйте список подкатегорий с помощью Transient API, если структура редко меняется, чтобы снизить нагрузку на базу.
- Для удобства пользователей добавьте кнопку сброса фильтра и сохраняйте выбранные значения при переходах.
Сравнение вариантов реализации фильтрации по подкатегориям
| Метод | Плюсы | Минусы | Рекомендуется для |
|---|---|---|---|
| Код на functions.php (как в статье) | Полный контроль, нет зависимостей от плагинов, легко кастомизируется | Требует знаний PHP, не подходит для новичков | Разработчики и опытные пользователи |
| Плагины фильтрации (например, WOOF, FacetWP) | Много функций & визуальная настройка | Могут замедлять сайт, платные версии для расширенных функций | Пользователи без навыков программирования |
| Кастомные темы с поддержкой фильтров | Интегрировано, часто оптимизировано | Зависимость от темы, ограниченная гибкость | Сайты с заранее выбранной темой |