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

    Для начала — маленькое лирическое отступление. Поручили тут недавно мне на работе сделать небольшую базку квартир для сайта агентства недвижимости. Да такую, чтобы можно было искать квартиры аж по 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-кода. Наслаждайтесь!

    Комментарии 27

      –1
      Спасиб. Плюсануть не могу. Сволочи заминусовали))) но очень полезно. Потому что сам сейчас сайт по недвижимеости буду делать и как раз на Modx :)
        0
        Рада, что понравилось :) На деле - не только недвижимость можно так оформить... на такой основе можно, например, и каталог товаров забацать! :)
          –1
          Ну я не хочу серьезно разбираться в Modx потому что планирую скоро писать сайты на RubyOnRails. "разбираться в Modx" - читать как "разбираться в PHP"
          Но на модх сделал уже 4 сайта. (один туристический сайт пока не доделал) . Работать в нем приятно :)
          PS. Спасиб за карму:)
            0
            не за что :) А вообще - в чём плюс MODx - как я и показала выше, собственно PHP-кода писать надо очень немного, а навыки шаблонизирования и работы со структурой где угодно пригодятся!

            P.S. Тоже поставила себе RoR в очередь на изучение.
              –1
              Не поверишь сколько всего у меня в очереди стоит :)) И дизайн и программинг и коммерция и сео и вообще всё что только можно. Только где же столько мозгов взять. Приходится круглыми сутками за компом сидеть :(
              • НЛО прилетело и опубликовало эту надпись здесь
                  0
                  дык вот и я про то же - просто времени не было в автоматическом режиме эти привязки кодить, дабы дважды не вписывать одно и то же :)
                    0
                    А можно попросить Вас несколько раскрыть мысль про "управляемую базу районов"? Как раз то, что мне нужно, но не предтавляю, как реализовывать. О каком снипете в данном случае идет речь?
                    Заранее спасибо :)
            0
            Спасибище тебе огромное, стоит точно такая же задача, решать собирался как раз на MODx, и вот оно! Все готовое и на блюдичке!Плюсовать так же жаль не могу)))Еще раз громадное спасибо!
              0
              не за что :) Давно исповедую принцип "научился сам - научи другого!" Главное, чтобы этот пост в поисковиках видно было - а то капец, тутариалов по движку же нет почти :)
                0
                если дадите разрешение, можем ваш материал на http://modx.ru/ повесить.
                  0
                  даю разрешение - пусть висит на благо народа! :)
                    0
                    я вам в icq пишу.
              –1
              Спасибо. Очень интересно. Буду использовать. Жалко не могу плюсовать(
                0
                можно и так. можно воспользоваться модулем tvExplorer.
                  0
                  tvExplorer - что за зверь?
                    0
                    часть tvEditor (http://modxcms.com/forums/index.php/topi…) позволяет делать формы выбора по TV, как, например, на сайте http://www.vsedveri.ru/ именно так и реализовано в правой колонке. Кстати, каталог на Ditto.

                    p.s. если кому нужна помощь по MODx обращайтесь на форум русской поддержки http://modxcms.com/forums/index.php#14
                      0
                      ага, посмотрела - оно-то забавно, но что-то уж больно много действий требует :) Уж по крайней мере поиск я бы сделала своим способом, как более простым. Единственное, редактор удобный, не отнять - вот ради редактора поставлю себе, опробую! Благодарю за наводку!
                        0
                        Level UP. Еще раз спасибо
                      0
                      хм, что-то я в официальном репозитории такого сниппета не нашла - действительно, а что это за зверь?
                      0
                      Ad_Astra, спасибо огромное! Радует. Все же действительно не зря я затеял здесь этот блог. Даже сопротивляющиеся (ранее) очень сильно им активно пользуются ;-) Глядишь, может действительно сможем сообщество таки организовать. Хоть и тянут все до сих пор в разные стороны.

                      Сам не могу писать опять, а на других смотреть приятно :-))
                        0
                        Плюс обязательно поставил бы, если бы мог! Спасибо за статью. Сейчас собираюсь делать каталог на модикс с поиском, и эта статья как раз актуальна! Пишите ещё =)
                          0
                          Не подскажете, а как сделать поиск "от" и "до"? Возможно нужно написание php скрипта, но к сожалению с языком не знаком. Вы тут все добрые такие, и мне не откажите в ответе:))
                            –1
                            Достаточно всего лишь подобрать параметры для Ditto
                            0
                            Большое спасибо…
                            а то справочной информации по этой CMS оооочень мало…
                              0
                              А на каком этапе происходит фильтрация значений из ПОСТ? Ведь эти значения скорее всего участвуют в запросе к БД?
                              Подозреваю что дитто производит фильтрацию… но все таки хотел бы узнать по точнее.
                                0
                                долго думала как же сделать если есть подкатегории и подподкатегории. Может кому пригодиться, надо в форму вызова Ditto добавить &depth=`3` число равно уровню подкатегорий.

                                А вот как организовать вариант ЛЮБОЙ я так и не придумала( Может кто подскажет?

                                Тоесть что б можно было выбрать ЛЮБОЙ город или ЛЮБОЕ кол-во комнат

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                Самое читаемое