Умные фильтры для туров: как я сделал поиск по датам, категориям и цене в 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 repeatertour_periodс полямиstartdatosиenddatos(форматd/m/Y);
нужно оставить только те посты, у которых хотя бы один период пересекается с выбранным диапазоном дат;
даты сравниваем какYmd(черезDateTime::createFromFormat('d/m/Y', ...)иformat('Ymd')). - Выведи весь код одним блоком 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 если используете свой вариант
🤓 Для самых любопытных
Самая хитрая часть — проверка пересечения дат:
php
if ( $ps <= $e && $pe >= $s ) {
// Нашли пересечение!
}
Перевод: "Если начало периода тура ≤ концу запроса И конец периода тура ≥ началу запроса — у нас есть пересечение!" Математика, которая работает!
🎬 Итог
Это решение экономит часы работы пользователей, повышает конверсию и делает ваш сайт профессиональнее. А главное — оно гибкое! Добавляйте новые фильтры, меняйте логику, адаптируйте под свои нужды.
Попробуйте! А если что-то пойдёт не так — пишите в комментариях, разберёмся вместе. Ведь в веб-разработке, как и в походах: иногда нужно просто найти правильный путь 😉
P.S. Код проверен в бою, но тестируйте на тестовом сайте. Вы же помните, что резервные копии — лучшие друзья разработчика?
P.P.S. Если нужна личная консультация бронируйте время тут