Умный фильтр или Фасетный поиск — это фильтр по категориям товара , которую можно видеть в крупных интернет магазинах и том же яндекс.маркете. Он помогает последовательно сортировать товары с нужными пользователю свойствами, отсеявая все лишнее. Это очень удобная опция, позволяющая быстро найти нужный товар или материал на сайте.
И так давайте перейдем непосредственно к установке и настройке нужных нам модулей
Установка модулей
Для начала нам понадобятся скачать и установить следующие модули: Search API, Search API Database Search, Entity API и Views.
На странице модулей включаем:
- Search API
- Search views
- Database search
- Entity API
- Views
- Views UI
- Ctools
Создание поискового сервера
Идем в Конфигурация > Поиск и метаданные > Search API (/admin/config/search/search_api) и нажимаем Добавить сервер.
Затем вводим имя сервера, в выпадающем списке Класс сервиса (Service class) выбираем Database service и сохраняем.
Создание индекса
Идем в Конфигурация > Поиск и метаданные > Search API (/admin/config/search/search_api), жмем Добавить сервер (Add index).
Вводим название индекса, в поле Тип элемента (Item type) выбираем ‘Материал‘, в поле Сервер выбираем Database server, жмем Создание индекс.
В открывшейся форме отмечаем галочками поля, по которым будет производится сортировка, и сохраняемся.
Чтобы можно было делать сортировку по названию ноды, включаем title и напротив него в выпадающем списке выбираем тип string, а не fulltext. По fulltext сортировку делать нельзя.
В следующей открывшейся форме Фильтры (workflow) я оставил все по умолчанию, переходим на вкладку Просмотр (Status), и нажимаем Индексировать сейчас (Index Now).
После завершения индексации, создадим страницу поиска.
Создание страницы поиска
Идем в Structure > Views и жмем Добавить новое представление (Add new view).
В новом представление в выпадающем списке Показать (Show) выбираем ранее созданный нами индекс, остальные поля (название, title и путь) заполняете так как вам нужно.
Далее нажимаем Сохранить и настроить (Continue & edit), настраиваем представление как обычно. В критериях фильтрации я добавил показ только опубликованных материалов и нужный тип node и настроил отображение необходимых полей (нужно добавить эти поля в индекс, чтобы иметь возможность фильтровать по ним).
На данном этапе с настройкой представления мы закончили, теперь перейдем непосредственно к фасетному фильтру.
Скачиваем модуль Facet API, устанавливаем его, и на странице модулей включаем два модуля: Facet API и Current Search Blocks. Последний создает блок с со списком активных фильтров и ссылки для их отмены. Также ключаем модуль Search facets он понадобится для интеграции ранее настроенного поиска и facet API.
Теперь идем в Конфигурация > Поиск и метаданные > Search API > Product Index (/admin/config/search/search_api/index/product_index/facets), здесь у нас появилась новая вкладка Фасеты (Facets), где нужно указать поля (проиндексированные ранее) для фильтра и настроить их отображение.
Для каждого от меченого поля будет автоматически создан отдельный блок на странице блоков, так что после того как нужные поля выбраны, идем на страницу блоков и размещаем их в нужном регионе и последовательности.
Current Search Blocks
На странице настройки блоков находим блок Current search: Standard и размещаем его в нужном нам месте. Затем идем в Конфигурация > Поиск и метаданные > 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: выбираем любое поле
После переходим на страницу настройки блоков, и размещаем только что созданный блок выше блоков фильтра. Теперь блоки фильтра будут отображаться там же, где и данный вспомогательный блок.
Смысл этих действий прост: чтобы блоки фильтра могли отображатся, им нужно получить информацию из базы данных. Вспомогательный блок как раз и производит этот запрос.
Множественный выбор (чекбоксы в фильтре)
Чтобы можно было выбрать одновременно несколько пунктов или категорий в нашем фильтре. Нужен модуль search api db. Поэтому скачиваем и устанавливаем его, после чего в настройках виджета меняем ‘ссылки’ на ‘ссылки с чекбоксами’, а оператор должен быть в положение ‘AND’.
Теперь в блоке фильтра можно выбирать несколько катигорий сразу:
Патчим Jquery UI Slider: исправляем выбор значений
Для выбора диапазона цен существует хороший модуль Search Api ranges, который интегрирует jQuery UI min/max slider в наш фильтр.
По умолчанию модуль имеет странное поведение — диапазон можно только уменьшить, но не увеличить, что несколько не удобно. Существует патч, который исправляет данный недочет. Я применял патч для версии 7x-1.5.
Страница обсуждения проблемы: https://drupal.org/node/1989776
Сам патч: http://drupalcode.org/project/search_api_ranges.git/commitdiff/433bbcd?h…
--- a/search_api_ranges.module
+++ b/search_api_ranges.module
@@ -144,11 +144,8 @@ function search_api_ranges_minmax($variables, $order = 'ASC') {
// otherwise our min/max would always equal user input.
$filters = &$query->getFilter()->getFilters();
foreach ($filters as $key => $filter) {
-
- // Check for array: old style filters are objects which we can skip.
- if (is_array($filter)) {
- if ($filter[0] == $variables['range_field'] || ($filter[0] != $variables['range_field'] && $filter[2] == '<>')) {
- $current_filter = $filters[$key];
+ if( isset($filter->tags) && is_array($filter->tags) ){
+ if( in_array('facet:'.$variables['range_field'], $filter->tags) ){
unset($filters[$key]);
}
}
Патчим JQuery UI Slider: настраиваем редирект
В версии модуля 7х-1.5 я столкнулся с тем, что если виджет слайдера расположен на странице, отличной от страницы поиска, то после изменения диапазона цены проиходило пере направление на текущую страницу, а не на страницу поиска.
Ошибка кроется в функии search_api_ranges_block_slider_view_form_submit() (файл search_api_ranges.module, строка 364).
Я не стал особо разбираться, что там и зачем, просто немного изменил код в строке 427:
- drupal_goto($path, array('query' => array($params), 'language' => $language));
+ drupal_goto($values['path'], array('query' => array($params), 'language' => $language));
после чего проблема решилась.