Умные фильтры для туров: как я сделал поиск по датам, категориям и цене в WordPress
Привет, друзья! Сегодня хочу поделиться с вами крутым решением, которое буквально преобразило поиск туров на одном из моих сайтов. Если вы работаете с WordPress, Elementor и ACF — этот материал для вас!
🤔 Проблема: пользователи не могут найти подходящий тур
Представьте: у вас есть сайт с турами, каждый тур имеет:
- Даты проведения (через ACF Repeater — несколько периодов!)
- Категории (стандартные WP)
- Произвольную таксономию «Цена» (да, именно таксономию, не поле!)
- И всё это нужно фильтровать одновременно
Обычные поисковые формы с этим не справляются. Нужно что-то особенное!
🎯 Решение: шорткод-универсал
Я создал шорткод [tour_filters], который генерирует умную форму поиска. Вот что он умеет:
1️⃣ Интеллектуальный выбор дат
Использовал flatpickr с испанской локализацией (проект был для испаноязычной аудитории). Пользователь выбирает диапазон дат — система ищет туры, которые пересекаются с этим периодом. И да, даже если у тура несколько периодов через ACF Repeater!
2️⃣ Динамические категории
Выпадающий список автоматически заполняется всеми существующими категориями сайта. Добавили новую категорию? Она сразу появится в фильтре — волшебство get_terms()!
3️⃣ Гибкая таксономия «Цена»
Здесь фишка в том, что «цена» — не число, а таксономия! Почему? Потому что иногда нужно группировать туры по ценовым сегментам: «Эконом», «Комфорт», «Люкс». Очень удобно для маркетинга!
🛠 Промпт который я использовал при обращении к ИИ
Для начала если еще не знаете что за GPTUNEL пройдите и зарегистрируйтесь.
Вот промпт который сразу создаст такой фильтр: Поправьте на свои значения
Хочу реализовать фильтры туров в WordPress через шорткод и последующую фильтрацию результатов поиска. Сделай полный рабочий пример кода (PHP + HTML + CSS + JS), который я могу вставить в functions.php:
- Шорткод
[tour_filters], который выводит форму фильтра:- поле выбора диапазона дат с помощью flatpickr (CDN), локализованного на испанский;
- селект категорий (таксономия
category); - селект цен (таксономия
precio); - кнопку отправки с текстом
Buscar Planes; - под кнопкой текстовую ссылку
Quitar Filtros, которая сбрасывает фильтры (удаляет из URL параметрыstart,end,cat,precio).
- Поля формы:
- визуальное поле с диапазоном дат (один input), только для выбора, без прямого ввода;
- два скрытых поля
startиendв форматеd/m/Y, которые заполняются при выборе дат в flatpickr; - селект категорий подгружается через
get_terms('category'); - селект цен подгружается через
get_terms('precio'); (возможно у вас другие или вообще хотите метки вывести) - выбранные значения должны сохраняться при перезагрузке (подставляться из
$_GET).
- Стили формы:
- вся форма в flex-контейнере с отступами между элементами;
- инпуты и селекты высотой 56px, скруглённые, с минимальной шириной 140px;
- кнопка оранжевая (#FF782A), белый текст, такая же высота и скругление;
- ссылка
Quitar Filtrosпод кнопкой, текстовая, подчёркнутая; - на мобильных (< 600px) элементы формы в колонку.
- Логика сброса фильтров:
- ссылка
Quitar Filtrosдолжна вести на тот же URL без параметровstart,end,cat,precio(используйremove_query_arg).
- ссылка
- Логика фильтрации:
- используем хук
add_filter('posts_results', '...', 20, 2)и фильтруем только на странице результатов поиска ($query->is_search()), не в админке; - из
$_GETберёмstart,end,cat,precio; - если задана категория — оставляем только посты, у которых есть term этой категории (
has_termпо таксономииcategory); - если задан
precio— оставляем только посты с этим term в таксономииprecio; - если заданы даты
startиend:- у постов есть ACF repeater
tour_periodс полямиstartdatosиenddatos(форматd/m/Y); - нужно оставить только те посты, у которых хотя бы один период пересекается с выбранным диапазоном дат;
- даты сравниваем как
Ymd(черезDateTime::createFromFormat('d/m/Y', ...)иformat('Ymd')).
- у постов есть ACF repeater
- используем хук
- Выведи весь код одним блоком PHP, без пояснений, чтобы я мог просто скопировать и вставить.Вы можете взять так же готовый код который у меня получился filtr — Это архив там в текстовом документе код. Можете взять скормить GPT и попросить доработать под себя
🛠 Технические вкусности (для тех, кто в теме)
Код состоит из двух основных частей:
Форма фильтров (tour_filters_form_shortcode)
-
Адаптивный дизайн (работает и на десктопе, и на мобилке)
-
«Умный» сброс фильтров через
remove_query_arg() -
Локализация flatpickr на лету
Фильтрация результатов (tour_filter_results)
-
Работает на странице поиска
-
Фильтрует по категориям через
has_term() -
Обрабатывает ACF Repeater с датами
-
Проверяет пересечение периодов (ваш запрос ∩ периоды тура)
✨ Почему этот подход — просто космос?
-
Не зависит от темы — работает с любой темой WordPress
-
Дружит с Elementor — просто вставляете шорткод куда нужно
-
Гибкость ACF — можете добавить любые дополнительные поля
-
Производительность — фильтрация происходит на этапе
posts_results, что эффективнее мета-запросов -
Масштабируемость — хотите добавить фильтр по «сложности маршрута»? Просто добавьте ещё одну таксономию!
💡 Пример из жизни
Пользователь выбирает:
- Даты: 15/06/2024 — 25/06/2024
- Категория: «Горные походы»
- Цена: «Комфорт»
Система находит все горные походы уровня «Комфорт», которые проводятся (хотя бы частично) в выбранные даты. И да, если тур идёт с 10/06 по 20/06 — он тоже подойдёт! Это же пересечение периодов!
🚀 Как внедрить у себя?
-
Скопируйте код в
functions.php(или в кастомный плагин) -
Добавьте шорткод
[tour_filters]через Elementor (блок «Шорткод») -
Создайте страницу поиска (или используйте существующую)
-
Настройте ACF поле
tour_period(Repeater с полямиstartdatos,enddatos) -
Добавьте таксономию
precioесли её нет
⚠️ Важные моменты
-
Код использует испанские названия полей (потому что проект был испанский)
-
Формат дат:
d/m/Y— адаптируйте под свою локализацию -
Фильтрация работает только на странице поиска
-
Не забудьте подключить flatpickr если используете свой вариант
🤓 Для самых любопытных
Самая хитрая часть — проверка пересечения дат:
if ( $ps <= $e && $pe >= $s ) { // Нашли пересечение! }
Перевод: «Если начало периода тура ≤ концу запроса И конец периода тура ≥ началу запроса — у нас есть пересечение!» Математика, которая работает!
🎬 Итог
Это решение экономит часы работы пользователей, повышает конверсию и делает ваш сайт профессиональнее. А главное — оно гибкое! Добавляйте новые фильтры, меняйте логику, адаптируйте под свои нужды.
Попробуйте! А если что-то пойдёт не так — пишите в комментариях, разберёмся вместе. Ведь в веб-разработке, как и в походах: иногда нужно просто найти правильный путь 😉
P.S. Код проверен в бою, но тестируйте на тестовом сайте. Вы же помните, что резервные копии — лучшие друзья разработчика?
P.P.S. Если нужна личная консультация бронируйте время тут