Что такое хук pre_get_posts и зачем он нужен в WooCommerce
Хук pre_get_posts позволяет вмешиваться в WP_Query до того, как запрос будет выполнен. В WooCommerce он часто используется для изменения списка товаров на страницах магазина — например, чтобы добавить фильтрацию по дополнительным параметрам, категориям или метаполям без создания отдельного плагина.
Это удобный способ кастомизировать вывод товаров без прямого редактирования шаблонов, что сохраняет совместимость с обновлениями WooCommerce.
Диагностика проблемы: стандартные фильтры WooCommerce не подходят
Иногда стандартных фильтров WooCommerce недостаточно, например:
- Необходима фильтрация по пользовательским метаполям (например, по цвету, материалу).
- Фильтрация должна работать на странице архива товаров, но стандартные виджеты не подходят.
- Требуется изменить порядок вывода товаров в зависимости от условий.
В таких случаях вмешательство в WP_Query через pre_get_posts — оптимальное решение.
Пошаговое решение: добавляем фильтр по метаполю "color"
1. Определяем, где подключать хук
Рекомендуется добавлять код в functions.php дочерней темы или в собственный плагин, чтобы сохранить изменения при обновлениях.
2. Пример кода для фильтрации товаров по метаполю "color" из GET-параметра
add_action('pre_get_posts', 'custom_filter_products_by_color');
function custom_filter_products_by_color($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
if (is_post_type_archive('product') || is_tax('product_cat')) {
if (!empty($_GET['color'])) {
$color = sanitize_text_field($_GET['color']);
$meta_query = $query->get('meta_query');
if (!$meta_query) {
$meta_query = [];
}
$meta_query[] = [
'key' => 'color',
'value' => $color,
'compare' => '=',
];
$query->set('meta_query', $meta_query);
}
}
}Здесь мы проверяем, что запрос относится к архиву товаров или категории, и если в URL есть параметр color, добавляем фильтрацию по метаполю.
3. Как добавить фильтр на фронтенде
Для удобства пользователей можно добавить форму фильтрации в шаблон:
<form method="get" action="">
<label for="color">Фильтр по цвету:</label>
<select name="color" id="color">
<option value="">Все</option>
<option value="red">Красный</option>
<option value="blue">Синий</option>
<option value="green">Зеленый</option>
</select>
<button type="submit">Применить</button>
</form>Проверка результата после внедрения
Чтобы проверить, что фильтр работает:
- Перейдите на страницу архива товаров, например:
https://example.com/shop/. - Добавьте к URL параметр фильтра, например:
?color=red. - Убедитесь, что на странице отображаются только товары, у которых в метаполе
colorзначениеred. - Проверьте, что при отсутствии параметра
colorвыводятся все товары.
Частые ошибки и как их исправить
- Нет результата фильтрации: Проверьте, что метаполе
colorсуществует и задано у товаров. Можно посмотреть через базу данных или в админке. - Фильтр не срабатывает на страницах категории: Убедитесь, что условие
is_tax('product_cat')прописано правильно, и запрос является главным ($query->is_main_query()). - Появляется 404 или пустая страница: Возможно, конфликт с другими плагинами или неправильная обработка
meta_query. Попробуйте временно отключить другие плагины и проверить. - Параметры URL не сохраняются при пагинации: Нужно добавить параметр
colorк ссылкам пагинации, например с помощью фильтраpaginate_links.
Практические советы по безопасности и производительности
- Санитизация входных данных: Всегда используйте
sanitize_text_field()или аналогичные функции для очистки GET/POST данных. - Оптимизация meta_query: Если фильтров несколько, объединяйте их в один массив
meta_queryс правильными условиямиrelation('AND' или 'OR'). - Кэширование: При сложных запросах используйте Object Cache или сторонние решения для снижения нагрузки на базу.
- Избегайте избыточных запросов: Проверяйте условие
is_main_query(), чтобы не влиять на административную панель и внутренние WP-запросы.
Таблица сравнения способов фильтрации товаров WooCommerce
| Метод | Плюсы | Минусы | Когда использовать |
|---|---|---|---|
| Виджеты WooCommerce (фильтры) | Простые в настройке, без кода | Ограничены стандартными полями | Базовая фильтрация по атрибутам |
| pre_get_posts с meta_query | Гибкая кастомизация, фильтрация по метаполям | Требует программирования, возможны ошибки | Фильтрация по кастомным полям, сложные условия |
| Плагины фильтрации (например, FacetWP) | Мощные, с UI, поддержка AJAX | Платные, нагрузка на сайт | Сложные фильтры без программирования |