Pull to refresh

Делаем поиск по множественным TV

Reading time3 min
Views7.6K
Для начала — маленькое лирическое отступление. Поручили тут недавно мне на работе сделать небольшую базку квартир для сайта агентства недвижимости. Да такую, чтобы можно было искать квартиры аж по 5 параметрам сразу — город, район, количество комнат, планировка и цена. Ну и чтобы всё это было встроено в админку и легко редактировалось, разумеется. А надо сказать, что я работала с разными CMS — от дорогого и тяжеловесного Битрикса до самописных простеньких движочков, и в конце концов остановила свой выбор на MODx — ибо, не сочтите за рекламу/антирекламу, но то, что на том же Битриксе делалось за неделю (а именно — несложный корпоративный сайтец), на MODx спокойно делается за день.

Я к чему это, собственно, пишу. В практически любой CMS для реализации этой задачи пришлось бы писать дополнительный код и всячески извращаться. В MODx же это решается при помощи исключительно стандартных средств движка, и единственная вещь, которую приходится писать «ручками» — это непосредственно сама форма поиска. Пусть неочевидно (пришлось всё же покопаться по документации, пока сообразила) — но всё ж полезно.

Итак, задача разбивается на следующие этапы:
  1. Создать TV для свойств, по которым будет происходить поиск.
    Задать шаблон и логику для выводов результатов поиска.
    Создать саму форму поиска.
    Думаю, тем, кто хорошо знаком с MODx, нет смысла объяснять, что такое TV. Наиболее близкий аналог, который мне доводилось видеть — это свойства инфоблока в Битриксе. Пусть это не совсем одно и то же, но логику построения в данном случае можно использовать схожую.

    Семантически наша база квартир будет представлять из себя контейнер с публикациями (выделенный в отдельную группу документов, чтобы не было путаницы). Одна квартира — одна публикация, и параметры TV в данном случае для каждой публикации о квартире исполнят роль этих самых свойств. Примерно вот так:

    структура документов
    свойства публикации

    Чтобы при редактировании публикации с квартирой у нас получалась вот такая вот красота, мы идём в «Управление ресурсами» -> «Параметры (TV)», и для каждого параметра задаём выпадающий список примерно вот так:

    задаём параметр

    Да, разделителем для возможных значений служит "||", а значение по умолчанию на всякий случай делаем пустым.

    Теперь создаём новый документ в корне сайта. Называем его как хотим, что-нибудь типа «поиск». И вместо того, чтобы писать свои сниппеты и всячески извращаться, используем магию стандартного и дико мощного Ditto. Вставляем в тело документа следующее:

    [!Ditto? &tpl=`Apartments` &startID=`52` &filter=`tvrooms,@EVAL return $_POST['rooms'];,1|tvcity,@EVAL return $_POST['city'];,1|tvregion,@EVAL return $_POST['region'];,1|tvplan,@EVAL return $_POST['plan'];,1|tvcost,@EVAL return $_POST['cost'];,1` &noResults=`Извините, недвижимости по Вашему запросу не найдено.`!]

    Разберём, что делает этот вызов.

    &tpl=`Apartments` — определяем, как будет называться чанк с шаблоном для вывода найденных публикаций. Обычный чанк для Ditto, думаю, не надо отдельно говорить, как его создавать.

    &startID=`52` — ID контейнера с публикациями, по которому делается выборка. В нашем случае, как видно на скриншоте, это 52.

    &filter=`tvrooms, EVAL return $_POST['rooms'];,1... — самая волшебная штука. Это, как можно догадаться, фильтр, по которому отсеиваются ненужные нам значения и выбираются нужные. В зацитированном логика такова: «отсеять все документы, значения TV-параметра rooms которого НЕ РАВНО значению php-переменной rooms из суперглобального массива $_POST».

    То есть у нас есть три аргумента, разделённых запятыми. Первый — это параметр, по которому фильтруем (если это TV-параметр — то добавляем tv к его названию для указания на это). Второй — это значение параметра. В данном случае мы используем вызов EVAL, чтобы выполнить PHP-код с прямым указанием на переменную из $_POST. Ну и третий параметр — это указатель на логический оператор, связывающий между собой параметр и значение. Единица означает «не равно», да (подробнее об этом можно прочитать вот тут). Ну и, собственно, такие правила фильтрации можно объединять при помощи символа "|", соответствующего логическому «ИЛИ». Что мы и делаем для того, чтобы объединить в один фильтр все наши TV-параметры.

    Кстати, обратите внимание, что названия TV-параметров и названия переменных в $_POST сделаны одинаковыми. Это для удобства, чтобы не было никакой путаницы.

    А теперь последний штрих — создаём чанк с формой поиска, выпадающие списки в которой называем — угадайте как? — да-да, именно так же, как TV-параметры. Значения option пишем те же, что и при задании параметров (пока не пробовала искать способ, чтобы это происходило автоматически, но попробую обязательно). А в атрибуте action тэга form указываем URL страницы поиска с вызовом Ditto. Называем чанк как хотим, например, SearchForm — и вставляем его на все страницы, с которых мы хотим производить поиск, при помощи вызова {{SearchForm}}. Вуаля!

    Так можно делать привязки и формы поиска по каким угодно расширенным параметрам, не написав при этом ни строчки PHP-кода. Наслаждайтесь!
Tags:
Hubs:
+5
Comments27

Articles