mFilter2

02 апреля 2017, 06:21

Сниппет реализует вторую половину компонента - фильтрацию найденных результатов.

Обладает огромным количеством настроек и работает, используя свой собственный класс фильтрации, который вы можете расширить. При небольших знаниях PHP и фантазии, вы можете организовать фильтрацию по любым позициям.

Параметры

Название По умолчанию Описание
&paginator pdoPage Сниппет для постраничной навигации, по умолчанию pdoPage. Вы можете указать набор параметров для него: &paginator=`pdoPage@myParams`.
&element mSearch2 Сниппет, который будет вызываться для вывода результатов работы, по умолчанию - mSearch2. Вы можете указать набор параметров для него: &element=`mSearch2@myParams`.
&sort Список полей ресурса для сортировки. Указывается в формате «таблица|поле:направление». Можно указывать несколько полей через запятую, например: «resource|publishedon:desc,ms|price:asc».
&filters resource|parent:parents Список фильтров ресурсов, через запятую. Указывается в формате «таблица|поле:метод».
&aliases Список псевдонимов для фильтров, которые будут использованы в URL фильтра, через запятую. Указывается в формате "таблица|поле==псевдоним". Например: "resource|parent==category".
&showEmptyFilters true Показывать фильтры всего с одним значением.
&resources Список ресурсов для вывода, через запятую. Этот список будет обработан другими параметрами, такими как &parents, &showDeleted, &showHidden и &showUnpublished.
&parents Список категорий, через запятую, для ограничения вывода результатов.
&depth 10 Глубина поиска ресурсов от каждого родителя.
&tplOuter tpl.mFilter2.outer Чанк оформления всего блока фильтров и результатов.
&tplFilter.outer.default tpl.mFilter2.filter.outer Стандартный чанк оформления одной группы фильтров.
&tplFilter.row.default tpl.mFilter2.filter.checkbox Стандартный чанк оформления одного фильтра в группе. По умолчанию выводится как checkbox.
&showHidden true Показывать ресурсы, скрытые в меню.
&showDeleted false Показывать удалённые ресурсы.
&showUnpublished false Показывать неопубликованные товары.
&hideContainers false Скрывать ресурсы-контейнеры.
&showLog false Показывать дополнительную информацию о работе сниппета. Только для авторизованных в контекcте «mgr».
&suggestions true Этот параметр включает предположительное количество результатов, которое показывается возле каждого фильтра. Отключите, если вы недовольны скоростью фильтрации.
&suggestionsMaxFilters 200 Максимальное количество операций фильтрации (не самих фильтров), для которых работают предварительные результаты. Если операций требуется больше - suggestions отключатся.
&suggestionsMaxFilters 1000 Максимальное количество ресурсов, для которых работают предварительные результаты. Если ресурсов будет больше - suggestions отключатся.
&suggestionsRadio Список фильтров через запятую, для которых возможен выбор только одного значения, например, элементы radio и select. Предсказания этих групп фильтров не суммируются между собой. Например: «resource|class_key,ms|new»
&toPlaceholders Если не пусто, mFilter2 сохранит все данные в плейсхолдеры: [[+filters]], [[+results]] и [[+total]] с префиксом, указанным в этом параметре. Например, если вы укажете &toPlaceholders=`my.`, то получите: [[+my.filters]], [[+my.results]] и [[+my.total]]
&toSeparatePlaceholders Работает так же как и &toPlaceholders, только в раздельные плейсхолдеры попадает еще и filters. Например, если вы укажете &toSeparatePlaceholders=`my.` и &filters=`tv|test,resource|pagetitle` то получите плейсхолдеры [[+my.results]], [[+my.total]], [[+my.tv|test]] и [[+my.resource|pagetitle]].
&filter_delimeter | Разделитель кодового имени таблицы и поля фильтра.
&method_delimeter : Разделитель полного имени фильтра и метода его обработки.
&values_delimeter , Разделитель значений фильтров в адресной строке сайта.
&tpls Список чанков для оформления строк, через запятую. Вы можете переключать их указанием в $_REQUEST параметра &tpl. 0 - это чанк по умолчанию, а дальше по порядку. Например: &tpls=`default,chunk1,chunk2`, для вывода товаров чанком "chunk1", нужно прислать в запросе $_REQUEST[tpl] = 1.
&forceSearch false Обязательный поиск для вывода результатов. Если нет поискового запроса - ничего не выводится.
&fields Список проиндексированных полей ресурса, через запятую, в которых нужно искать. Вы можете также указать вес для каждого поля, через запятую: &fields=`pagetitle:5,content:3,comment:1`. По умолчанию используется системная настройка mse2_index_fields.
&onlyIndex false Включить режим поиска только по индексу слов, и отключить дополнительные результаты, найденные простым поиском через LIKE.
&showSearchLog false Показывать подробную информацию о начислении баллов поиска ресурсам при включенном &showLog.
&sortAliases JSON массив с псевдонимами классов для сортировки. Подробности ниже.
&filterOptions JSON строка с переменными для javascript фильтра. Подробности ниже.
&ajaxMode default Режим ajax пагинации: default, scroll или button. Работает аналогично pdoPage, только без параметра &ajaxHistory.

Принцип работы

При первом запуске на странице сниппет получает нужные для фильтрации ресурсы, которые можно указать ему двумя способами:

  • Прямое указание параметров, таких как &parents, &resources, &showHidden и т.д. Они будут переданы в сниппет, указанный в &element и он вернёт нужные id.
  • Поиск по алгоритму mSearch2, если в $_REQUEST[&queryVar] что-то есть. При этом, найденные id также пройдут проверку указанными параметрами.

Затем сниппет смотрит настройки фильтров и генерирует данные для них. После чего сохраняет настройки в сессию (для ajax запросов) и выводит оформленные чанки.

Дальше вы кликаете по фильтрам, скрипты ловят их изменение, отправляют запрос на сервер и обновляют содержимое страницы. Всё полностью автоматизированно, вам нужно только указать верные параметры и настроить чанки.

Скрипты и стили

При работе mFilter2 регистрируются скрипты и стили, указанные в системных настройках:

  • mse2_frontend_js - стандартный javascript, по умолчанию /assets/components/msearch2/js/web/default.js
  • mse2_frontend_css - стандартные css стили оформления, по умолчанию /assets/components/msearch2/css/web/default.css

Если вы хотите внести какие-то изменения в стандартные файлы, нужно их переименовать и указать новые значения в системных настройках, иначе все ваши изменения будут перезаписаны при очередном обновлении.

Также вы можете менять переменные стандартного фильтра, указав их в виде JSON строки в параметре &filterOptions:

[[!mFilter2?
    &parents=`0`
    ...
    &filterOptions=`{
        "pagination": "#mse2_pagination",
        "selected_values_delimeter": ", "
    }`
]]

Они заменят переменные объекта mSearch2.options javascript фильтра на фронтенде.

Например, вот так можно отключить автоматическую отправку формы с фильтрами при изменении:

&filterOptions=`{"autoLoad":0}`

Тогда в форме по умолчанию появится кнопка "Отправить" и нужно будет нажимать на неё.

Особенности

  • Для правильной работы необходимо, чтобы все элементы фильтра располагались в одном блоке с #mse2_mfilter. Именно так прописано с стандартном чанке tpl.mFilter2.outer.
  • Скрипт работает через Ajax, сохраняя при этом параметры с адресной строке через HistoryAPI. То есть, у вас всегда есть прямые рабочие ссылки на состояние фильтров.
  • Для реализации цифровых слайдеров скрипт использует jQueryUI.slider, который подключается автоматически, если нужен.
  • По умолчанию всё оформление рассчитано на Bootstrap 3.
  • Стандартная комплектация рассчитана так, чтобы работать при минимальном вызове [[!mFilter2]] и установленном Bootstrap 3. Если у вас что-то "сломалось", после того, как вы изменили чанк - смотрите, что именно вы изменили.

Чанки и оформление

У mFilter2 есть один основной чанк, куда выводятся все результаты его работы, с основными плейсхолдерами: [[+filters]] и [[+results]].

За результаты отвечают два сниппета: по умолчанию pdoPage, который запускает mSearch2 для вывода собственно строчек с документами. Вы можете указать и другие сниппеты, например getPage и msProducts:

[[!mFilter2?
    &paginator=`getPage`
    &element=`mSearch2`
]]

Для каждого фильтра можно указать 2 собственных чанка:

  • &tplFilter.outer.таблица|поле=`tpl.mFilter2.filter.outer` - чанк-обертка, в который вставляются строки с фильтрами (плейсхолдер [[+rows]]).
  • &tplFilter.row.таблица|поле=`tpl.mFilter2.filter.checkbox` - чанк для оформления одного параметра фильтра, по умолчанию - это checkbox. В комплекте есть еще и чанк для чисел - его нужно указать самостоятельно.

Например, вызов слайдера для цены товара:

[[!mFilter2?
    &class=`msProduct`
    &element=`msProducts`
    &parents=`0`
    &filters=`
        ms|price:number
    `
    &tplFilter.outer.ms|price=`tpl.mFilter2.filter.slider`
    &tplFilter.row.ms|price=`tpl.mFilter2.filter.number`
]]

А вот вывод родителей документов в элементе select:

[[!mFilter2?
    &parents=`0`
    &filters=`
        resource|parent:parents
    `
    &tplFilter.outer.resource|parent=`tpl.mFilter2.filter.select`
    &tplFilter.row.resource|parent=`tpl.mFilter2.filter.option`
    &suggestionsRadio=`resource|parent`
]]

Указание поля select в &suggestionsRadio активирует правильную работу предсказаний с этим фильтром. Блок select даёт выбирать только одно значение, поэтому у соседних значений не должно быть плюсиков перед предсказаниями.

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

Фильтры

Построение фильтров указывается через один параметр &filters, в формате кодовое_имя_таблицы/поле:фильтр. За один раз можно указать сколько угодно фильтров через запятую.

Соотношение реальных таблиц и кодовых имён:

  • resource (modResource) - выборка полей ресурса, таких как pagetitle, longtitle и др.
  • tv (modTemplateVar) - выборка ТВ параметров.
  • ms (msProductData) - выборка полей товара miniShop2, таких как price, article, weight и др.
  • msoption (msProductOption) - выборка опций товаров miniShop2, таких как size, color, tags и др.
  • msvendor (msVendor) - выборка свойств производителя товара, таких как title, country, phone и др.

Если вы не указываете кодовое имя таблицы, то будет использовано resource. А если вы не указываете фильтр, то будет использован default.

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

Пример фильтров в работе:

[[!mFilter2?
    &filters=`
        parent:grandparents,
        createdon:year,
        createdon:month,
        tv|radio:boolean,
        createdby:fullname
    `
]]

В комплекте с mFilter2 идёт несколько стандартных методов фильтрации, которые позволяют сделать вывод фильтров более приятным.

default

Обычный, стандартный фильтр, рассчитанный на вывод чекбоксов. Применяется ко всем полям, для которых не указан свой фильтр.

number

Фильтр для чисел от min до max. При его использовании желательно указывать соответствующие чанки, чтобы вывод был оформлен слайдером.

[[!mFilter2?
    &filters=`
        template:number
    `
    &tplFilter.outer.resource|template=`tpl.mFilter2.filter.slider`
    &tplFilter.row.resource|template=`tpl.mFilter2.filter.number`
]]

boolean

Фильтр для вывода параметров да\нет. Например, опубликован ли ресурс, скрыт в меню, доступен для поиска и т.д. Если не указать фильтр boolean у таких полей, то вы получите 0 и 1 в значениях. А если указать - то "да" и "нет".

[[!mFilter2?
    &filters=`
        isfolder:boolean
    `
]]

parents, categories и grandparents

Следующие три фильтра применяются только к полю parent ресурса.

Parents выводит имена двух родителей, через разделитель. Он включен по умолчанию.

[[!mFilter2?
    &filters=`
        parent:parents
    `
]]

Categories выводит имя непосредственного родителя.

[[!mFilter2?
    &filters=`
        parent:categories
    `
]]

Grandparents выводит имена родителей-дедушек и предназначен для больших каталогов. Если "дедушки" нет, то будет выведен непосредственный родитель.

[[!mFilter2?
    &filters=`
        parent:grandparents
    `
]]

vendors

Фильтр для вывода имён производителей товаров miniShop2. Применяется только к полю vendor таблицы ms.

[[!mFilter2?
    &where=`{"class_key":"msProduct"}`
    &filters=`
        ms|vendor:vendors
    `
]]

fullname

Этот фильтр выводит полное имя пользователя. Может применяться к любому полю, содержащему id юзера.

[[!mFilter2?
    &filters=`
        createdby:fullname
    `
]]

year

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

[[!mFilter2?
    &filters=`
        createdon:year
    `
]]

month

Этот фильтр применяется к полям с датой и выводит месяц прописью, подставляя его название из словаря компонента.

day

Этот фильтр применяется к полям с датой и выводит день.

Псевдонимы фильтров

В последних версиях дополнения введена специальная система псевдонимов для фильтров, чтобы сделать их использование более удобным.

Вы можете указать список замены длинных названий фильтров на более короткие и понятные. Например:

[[!mFilter2?
    &parents=`0`
    &element=`msProducts`
    &aliases=`
        ms|price==price,
        resource|parent==parent,
    `
    &filters=`
        ms|price:number,
        parent:parents,
        parent:categories,
    `
    &class=`msProduct`
    &tplFilter.outer.price=`tpl.mFilter2.filter.slider`
    &tplFilter.row.price=`tpl.mFilter2.filter.number`
]]

В результате, url будут вот такие:

site.com/mfilter2?price=102,750&parent=10,12,15

Обратите внимание, что указание псевдонимов влияет и на указание параметров шаблонов. То есть, если для ms|price указан псевдоним, то и чанк нужно указывать как &tplFilter.row.price, а не &tplFilter.row.ms|price.

&filters=`
    resource|parent:categories,
    resource|parent:grandparents,
`

Если какое-то поле указано 2 и более раз, то его имя прописывается как поле-фильтр и получается

parent-categories и parent-grandparents

Соответственно, псевдонимы должны быть такими:

&aliases=`
    resource|parent-categories==categories,
    resource|parent-grandparents==grandparents,
`

Ну а чанки указываются уже по псевдониму:

&tplFilter.row.categories=`tpl.mFilter2.filter.checkbox1`
&tplFilter.row.grandparents=`tpl.mFilter2.filter.checkbox2`

Предварительные результаты

Предварительные результаты - это маленькие циферки рядом с каждым фильтром, которые показывают, сколько вы получите результатов, если кликните на него.

При каждом клике это значение пересчитывается для всех фильтров, с учетом текущего состояния. Для этого скрипт пробегает по каждому варианту и считает, сколько будет результатов, если его активировать.

То есть, у вас может быть несколько десятков (сотен, тысяч) дополнительных фильтраций. Зачем это нужно?

  • Посетитель сразу знает, что получит при клике, и куда лучше кликнуть.
  • Позволяет отключать те комбинации фильтра, которые ничего не выведут. То есть, посетитель не увидит "По вашему запросу ничего не найдено".

Функция безусловно приятная и полезная, но очень тяжелая для работы. Она напрямую зависит от количества фильтруемых результатов и параметров фильтров - то есть, сделать так, чтобы она не тормозила вообще нигде, невозможно.

Поэтому она отключается автоматически для больших каталогов регулируемыми параметрами &suggestionsMaxFilters и &suggestionsMaxResults. Также вы можете полностью отключить её общим параметром

&suggestions=`0`

При активации этой опции вы получите максимальную скорость, но циферки рядом с фильтром пропадут.

Сортировка результатов

mFilter2 умеет сортировать сразу по нескольким полям таблицы.

Формат указания параметра &sort очень похож на работу &filters:

&sort=`
    resource|publishedon:asc,
    resource|createdby:desc
`

Тут нужно знать следующее: в зависимости от используемого сниппета вывода результатов, псевдонимы базы данных могут отличаться. Например в mSearch2 ресурсы джоинятся под псевдонимом modResource, а в msProducts - как msProduct.

Поэтому при работе с msProducts нужно указывать вот так:

&sort=`
    ms_product|publishedon:asc,
    ms_product|createdby:desc,
    ms|price:asc,
    ms_vendor|name:desc
`

В классе фильтров за эту логику отвечает метод getSortFields(), который вы можете изменить, как и все остальные.

По умолчанию заданы вот такие соответствия для псевдонимов таблиц:

  • ms → Data
  • ms_product → msProduct
  • ms_vendor → Vendor
  • tv → TV
  • resource → modResource

Вот что сниппет получит при обработке параметров из последнего примера:

`msProduct`.`publishedon` ASC, `msProduct`.`createdby` DESC, `Data`.`price` ASC, `Vendor`.`name` DESC

То есть, &sort напрямую завязан на сниппет, выбирающий данные, и то, как у него внутри соединены таблицы. Поэтому, при любых ошибках сортировки нужно смотреть лог работы и проверять системный журнал.

Если вам не хватает встроенных псевдонимов, вы можете добавить свои собственные через параметр &sortAliases. Например, для фильтрации тикетов:

[[!mFilter2?
    &parents=`0`
    &class=`Ticket`
    &element=`getTickets`
    &sortAliases=`{"ticket":"Ticket"}`
    &sort=`ticket|createdon:desc,ticket|pagetitle:asc`
    &showLog=`1`
]]

Еще пример - сортировка по опции товара miniShop2:

[[!mFilter2?
    &parents=`0`
    &element=`msProducts`
    &leftJoin=`{
        "Option": {
            "class": "msProductOption",
            "on": "Option.key = 'test1' and Option.product_id = msProduct.id"
        }
    }`
    &sortAliases=`{"msoption":"Option"}`
    &sort=`msoption|value:asc`
]]

Присоединяем опцию test1, добавляем для этой таблицы псевдоним и сортируем по значению присоединённой опции.

Javascript

Вся работа фильтров обеспечивается скриптом default.js, который идёт в комплекте. Путь к нему указывается в системной настройке mse2_frontend_js, так что, если вы захотите внести изменения, просто переименуйте этот файл и укажите новое название в настройке - чтобы при обновлении дополнения он не был перезаписан.

Все методы находятся в одном объекте mSearch2. Программно отправить форму, например, можно вот так:

mSearch2.submit();

А сбросить значения так:

mSearch2.reset();

При обновлении фильтров срабатывает событие mse2_load:

$(document).on('mse2_load', function(e, data) {
    console.log(e, data);
});

Вы можете использовать это событие для дополнительной обработки значений фильтра.

Лексиконы

Для оформления фильтров используются записи из лексикона. Если вы добавили новый фильтр и он отображается непонятной длинной надписью на английском - это значит, что её нужно добавить в словарь mSearch2.