Facet API или фасетный поиск в Drupal
Фасетный поиск (он же "умный фильтр") - та самая штука, которую можно видеть в крупных интернет магазинах бытовой техники и электроники: Связном, М-видео, Ситилинке и том же яндекс.маркете. Он позволяет последовательно выбрать товары с нужными свойствами, отсеяв все лишнее. Это мега-удобная вещь, и сейчас некоторые движки интернет магазинов имеют подобный функционал либо в виде модулей, либо 'из коробки'. Пример реализации такого поиска на друпале можно посмотреть в демке нашего готового решения Интернет магазина.
Недавно мне поступил заказ на доработку сайта, торгующего кондиционерами, где мы помимо прочего решили прикрутить фасетный поиск. Несмотря на наличие готовых модулей, процесс оказался не таким простым, как я ожидал: во-первых, сама настройка модулей содержит довольно много шагов, во-вторых, некоторые модули пришлось патчить, чтобы избавиться от багов или добиться нужного поведения. В этой статье я расскажу, что и как было сделано.
Необходимые модули
Для первичной настройки нам понадобятся следующие модули: Search API, Search API Database Search, Entity API иViews.
Так же можно установить с помощью drush
$ drush dl search_api search_api_db entity views ctools
В управлении модулями устанавливаем:
- Search API
- Search views
- Database search
- Entity API
- Views
- Views UI
- Ctools
Добавляем поисковый сервер
В Configuration -> Search API и нажимаем Add server.
Вводим имя сервера (я назвал его 'Database server'), в выпадающем списке Service classвыбираем Database service и сохраняем.
Создание индекса базы данных
Там же в Configuration -> Search API, нажимаем Add index.
Вводим название индекса (я назвал 'Product index'), Item type выбираем 'Node', в списке серверов выбираем созданный в предыдущем шаге Database server, жмем Create index.
В открывшейся форме выбираем поля, по которым будет производится поиск, сохраняем.
Совет: чтобы можно было в дальнейшем делать сортировку по названию ноды, включаем title и напротив него в выпадающем списке выбираем тип string, а не fulltext. По fulltext сортировку делать нельзя.
В следующей открывшейся форме (workflow) ничего не меняем, a переходим на вкладку Status (Просмотр), и нажимаем Index Now (Проиндексировать сейчас).
Наш контент проиндексирован, теперь создадим страницу поиска.
Создание страницы выдачи поиска
Создаем новое представление в Structure -> Views и жмем Add new view.
В открывшейся форме в выпадающем списке Show выбираем наш ранее созданный индекс (в данном случае Product index), остальные поля (название, title и путь) заполнем по своему усмотрению.
После этого нажимаем Continue & edit и настраиваем представление как обычно. Я добавил в критерии фильтрации показ только опубликованных материалов и нужный тип ноды, ну и настроил отображение необходимых полей (вы должны добавить эти поля в индекс, чтобы иметь возможность фильтровать по ним).
Создание фасетного поиска
Устанавливаем модуль Facet API, и списке модулей находим два новых пункта: собственно Facet API и Current Search Blocks. Последний создает блок с со списком активных фильтров и ссылки для их отмены. Включаем оба, а также модуль Search facets для интеграции ранее настроенного поиска и facet API.
Теперь в Configuration > Search API > Product Index, здесь у нас появилась новая вкладка Facets, где можно указать поля (проиндексированные ранее) для фильтра и виджеты.
Для индексации отмечаем поля которые должны отображатся в блоке.
Каждому полю соответствует отдельный блок, так что после того, нужные поля выбраны, идем в настройки блоков и размещаем их в нужном регионе и последовательности.
Current Search Blocks
В тех же в управлении блоков находим блок Current search: Standard и размещаем в нужном месте. Потом идем в Configuration > Current Search Block > Standart, и в самом низу находим настройки видимости: ставим либо третий, либо последний пункт (Display when either keywords are entered one or more facet items are active).
Вывод фильтра на странице представления
Изначально блок с ссылками фильтра отображается только на соответствующей ему странице поиска, но иногда нужно, чтобы этот блок отображался и на других страницах. Сделать это просто, хотя и не очевидно. Идем в настройки ранее созданного представления, и добавляем блок Facets block.
В настройках блока ставим:
- Hide block: Yes
- Search page path: путь к странице поиска
- Facet field: выбираем любое поле
Далее в настройки блоков, и размещаем наш блок выше блоков фильтра. Теперь блоки фильтра будут отображаться там же, где и данный вспомогательный блок.
Смысл же всех этих действий прост: чтобы блоки фильтра могли отобразится, им нужно получить информацию из базы данный (поля, кол-во элементов и т.д.). С помощью данного блока как раз и происходит этот запрос, в результате фильтр может быть отображен на любой странице.
Множественный выбор с чекбоксами
Мне также хотелось, чтобы можно было выбрать одновременно несколько брендов или категорий в нашем фильтре. Нужный функционал обнаружился в dev-версии модуля search api db. Поэтому скачиваем dev-версию, после чего в настройках виджета меняем 'ссылки' на 'ссылки с чекбоксами', а оператор ставим 'OR' вместо 'AND'.
Теперь в фильтре можно выбирать несколько позиций сразу: