Диагностика проблемы: почему стандартные фильтры WooCommerce не всегда подходят
WooCommerce предлагает базовые фильтры каталога товаров, но часто возникает необходимость создать собственные фильтры по произвольным параметрам (например, по метаполям, пользовательским таксономиям или сложным условиям). Попытка модифицировать запрос без правильного использования pre_get_posts может привести к неисправностям: фильтры не срабатывают, страница товаров выводит пустой результат или нарушается пагинация.
Пошаговое решение: добавляем кастомные фильтры через pre_get_posts
1. Определяем место для кода
Лучше всего добавить код в файл functions.php вашей дочерней темы или в отдельный плагин для кастомных функций.
2. Проверяем, что запрос именно для главной страницы магазина
function custom_woocommerce_filter_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( is_post_type_archive( 'product' ) || is_tax( 'product_cat' ) || is_tax( 'product_tag' ) ) {
// Здесь добавим логику фильтрации
}
}
add_action( 'pre_get_posts', 'custom_woocommerce_filter_query' );3. Добавляем фильтр по произвольному метаполю
Допустим, у товаров есть метаполе _custom_color, по которому надо фильтровать.
function custom_woocommerce_filter_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( is_post_type_archive( 'product' ) || is_tax( 'product_cat' ) || is_tax( 'product_tag' ) ) {
if ( ! empty( $_GET['filter_color'] ) ) {
$meta_query = array(
array(
'key' => '_custom_color',
'value' => sanitize_text_field( wp_unslash( $_GET['filter_color'] ) ),
'compare' => '=',
),
);
$query->set( 'meta_query', $meta_query );
}
}
}
add_action( 'pre_get_posts', 'custom_woocommerce_filter_query' );4. Обрабатываем фильтр по пользовательской таксономии
Если в WooCommerce добавлена своя таксономия, например product_brand, фильтр можно добавить так:
function custom_woocommerce_filter_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( is_post_type_archive( 'product' ) || is_tax( 'product_cat' ) || is_tax( 'product_tag' ) ) {
$tax_query = array();
if ( ! empty( $_GET['filter_brand'] ) ) {
$tax_query[] = array(
'taxonomy' => 'product_brand',
'field' => 'slug',
'terms' => sanitize_text_field( wp_unslash( $_GET['filter_brand'] ) ),
);
}
if ( $tax_query ) {
$query->set( 'tax_query', $tax_query );
}
}
}
add_action( 'pre_get_posts', 'custom_woocommerce_filter_query' );5. Объединяем несколько условий
Можно комбинировать meta_query и tax_query, добавляя несколько условий:
function custom_woocommerce_filter_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( is_post_type_archive( 'product' ) || is_tax( 'product_cat' ) || is_tax( 'product_tag' ) ) {
$meta_query = array();
$tax_query = array();
if ( ! empty( $_GET['filter_color'] ) ) {
$meta_query[] = array(
'key' => '_custom_color',
'value' => sanitize_text_field( wp_unslash( $_GET['filter_color'] ) ),
'compare' => '=',
);
}
if ( ! empty( $_GET['filter_brand'] ) ) {
$tax_query[] = array(
'taxonomy' => 'product_brand',
'field' => 'slug',
'terms' => sanitize_text_field( wp_unslash( $_GET['filter_brand'] ) ),
);
}
if ( $meta_query ) {
$query->set( 'meta_query', $meta_query );
}
if ( $tax_query ) {
$query->set( 'tax_query', $tax_query );
}
}
}
add_action( 'pre_get_posts', 'custom_woocommerce_filter_query' );Проверка результата после внедрения
- Откройте страницу магазина или категорий товаров.
- Добавьте в URL параметры фильтра, например:
?filter_color=red&filter_brand=nike. - Проверьте, что список товаров изменился согласно фильтрам.
- Убедитесь, что пагинация и сортировка работают корректно.
- Проверьте, что в админке (редакторе запросов) нет ошибок.
Частые ошибки и как их исправить
- Фильтр не срабатывает — возможно, не проверяется
$query->is_main_query(). Убедитесь, что код внутри блока для основного запроса. - Пагинация ломается — если меняете параметры запроса, не забудьте, что
posts_per_pageи другие параметры должны сохраняться или корректно переустанавливаться. - Пустой результат — проверьте правильность ключей метаполей и значений фильтров, используйте
var_dump($query->query_vars)для отладки. - Фильтр не применяется на страницах архива — проверьте условия
is_post_type_archiveиis_tax, возможно, нужно расширить список проверок.
Практические советы по безопасности и производительности
- Всегда используйте
sanitize_text_fieldиwp_unslashдля очистки входящих данных из$_GET. - Избегайте тяжелых запросов с большим числом
meta_query, они сильно влияют на производительность БД. - При необходимости кешируйте результаты фильтрации с помощью transient API или внешних кешей.
- Если фильтров много, подумайте о реализации AJAX-фильтров, чтобы уменьшить нагрузку и улучшить UX.
Сравнение способов фильтрации в WooCommerce
| Метод | Плюсы | Минусы | Когда использовать |
|---|---|---|---|
| Стандартные фильтры WooCommerce | Простота, интеграция с шаблонами | Ограниченные возможности кастомизации | Базовые фильтры по категориям и атрибутам |
Хук pre_get_posts с meta_query и tax_query | Гибкость, точечная настройка | Сложность, возможные проблемы с производительностью | Кастомные фильтры по метаполям и таксономиям |
| Плагины фильтров (например, FacetWP, Filter Everything) | Быстрая реализация, готовые UI | Зависимость от стороннего кода, платные версии | Если нет ресурсов на кастомную разработку |