mFilter2
mFilter2 — Сниппет реализует фильтрацию найденных результатов.
Оглавление
mFilter2 — Сниппет реализует фильтрацию найденных результатов.
Обладает огромным количеством настроек и работает, используя свой собственный класс фильтрации, который вы можете расширить. При небольших знаниях 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 | Показывать дополнительную информацию о работе сниппета. Только для авторизованных в контексте «mgr». |
&suggestions | true | Этот параметр включает предположительное количество результатов, которое показывается возле каждого фильтра. Отключите, если вы недовольны скоростью фильтрации. |
&suggestionsMaxFilters | 200 | Максимальное количество операций фильтрации (не самих фильтров), для которых работают предварительные результаты. Если операций требуется больше — suggestions отключатся. |
&suggestionsMaxResults | 1000 | Максимальное количество ресурсов, для которых работают предварительные результаты. Если ресурсов будет больше — suggestions отключатся. |
&suggestionsRadio | Список фильтров через запятую, для которых возможен выбор только одного значения, например, элементы radio и select. Предсказания этих групп фильтров не суммируются между собой. Например: «resource|class_key, ms|new» | |
&suggestionsSliders | true | Активирует работу предположительных результатов со слайдерами, увеличивая при этом общее количество фильтраций. |
&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 | Включить режим поиска только по индексу слов, и отключить дополнительные результаты, найденные простым поиском через LIKE. | |
&showSearchLog | Показывать подробную информацию о начислении баллов поиска ресурсам при включенном &showLog. | |
&sortAliases | JSON массив с псевдонимами классов для сортировки. Подробности ниже. | |
&filterOptions | JSON строка с переменными для javascript фильтра. Подробности ниже. | |
&ajaxMode | Режим 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:
/* modParser */
[!mFilter2?
&parents=`0`
&filterOptions=`{"pagination": "#mse2_pagination","selected_values_delimeter": ", "}`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'parents' => 0,
'filterOptions' => '{"pagination": "#mse2_pagination","selected_values_delimeter": ", "}
])}
Они заменят переменные объекта mSearch2.options
javascript фильтра на фронтенде. Еще один пример, изменить стандартную кнопку пагинации «Загрузить еще»:
/* modParser */
[[!mFilter2?
&ajaxMode=`button`
&filterOptions=`{"more": ".btn-default", "more_tpl": "<a class='btn_more'>Загрузить еще</a>"}`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'ajaxMode' => 'button',
'filterOptions' => '{"more": ".btn-default", "more_tpl": "<div class=\"btn_wrapper\"><button class=\"btn btn-default\">Загрузить еще</button></div>"}',
])}
А вот так можно отключить автоматическую отправку формы с фильтрами при изменении:
/* modParser */
[[!mFilter2?
&parents=`0`
&filterOptions=`{"autoLoad":0}`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'parents' => 0,
'filterOptions' => '{"autoLoad": "0"}
])}
После включения этой опции, в форме по умолчанию появится кнопка «Отправить» и для применения фильтров, нужно будет нажимать на неё.
Особенности
- Для правильной работы необходимо, чтобы все элементы фильтра располагались в одном блоке с
#mse2_mfilter
. Именно так прописано в стандартном чанке tpl.mFilter2.outer. - Скрипт работает через Ajax, сохраняя при этом параметры в адресной строке через HistoryAPI. То есть, у вас всегда есть прямые рабочие ссылки на состояние фильтров.
- Для реализации цифровых слайдеров скрипт использует jQueryUI.slider, который подключается автоматически, если нужен.
- По умолчанию всё оформление рассчитано на Bootstrap 3.
- Стандартная комплектация рассчитана так, чтобы работать при минимальном вызове
[[!mFilter2]]
и установленном Bootstrap 3. Если у вас что-то «сломалось», после того, как вы изменили чанк — смотрите, что именно вы изменили.
Чанки и оформление
У mFilter2 есть один основной чанк, куда выводятся все результаты его работы, с основными плейсхолдерами: [[+filters]]
и [[+results]]
.
За результаты отвечают два сниппета: по умолчанию pdoPage, который запускает mSearch2 для вывода собственно строчек с документами. Вы можете указать и другие сниппеты, например getPage и msProducts:
/* modParser */
[[!mFilter2?
&paginator=`getPage`
&element=`mSearch2`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'paginator' => 'getPage',
'element' => 'mSearch2'
])}
Для каждого фильтра можно указать 2 собственных чанка:
&tplFilter.outer.таблица|поле=`tpl.mFilter2.filter.outer`
— чанк-обертка, в который вставляются строки с фильтрами (плейсхолдер[[+rows]]
).&tplFilter.row.таблица|поле=`tpl.mFilter2.filter.checkbox`
— чанк для оформления одного параметра фильтра, по умолчанию — это checkbox. В комплекте есть еще и чанк для чисел — его нужно указать самостоятельно.
Например, вызов слайдера для цены товара:
/* modParser */
[[!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`
]]
/* pdoParser */
{$_modx->runSnippet('!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:
/* modParser */
[[!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`
]]
/* pdoParser */
{$_modx->runSnippet('!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
.
Вы можете указывать несколько фильтров для одного поля, например для раздельной фильтрации по году и месяцу.
Пример фильтров в работе:
/* modParser */
[[!mFilter2?
&filters=`parent:grandparents,createdon:year,createdon:month,tv|radio:boolean,createdby:fullname`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'filters' => 'parent:grandparents,createdon:year,createdon:month,tv|radio:boolean,createdby:fullname',
])}
В комплекте с mFilter2 идёт несколько стандартных методов фильтрации, которые позволяют сделать вывод фильтров более приятным.
default
Обычный, стандартный фильтр, рассчитанный на вывод чекбоксов. Применяется ко всем полям, для которых не указан свой фильтр.
number
Фильтр для чисел от min до max. При его использовании желательно указывать соответствующие чанки, чтобы вывод был оформлен слайдером.
/* modParser */
[[!mFilter2?
&filters=`template:number`
&tplFilter.outer.resource|template=`tpl.mFilter2.filter.slider`
&tplFilter.row.resource|template=`tpl.mFilter2.filter.number`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'filters' => 'template:number',
'tplFilter.outer.resource|template' => 'tpl.mFilter2.filter.slider',
'tplFilter.row.resource|template' => 'tpl.mFilter2.filter.number',
])}
boolean
Фильтр для вывода параметров да\нет. Например, опубликован ли ресурс, скрыт в меню, доступен для поиска и т. д. Если не указать фильтр boolean у таких полей, то вы получите 0 и 1 в значениях. А если указать — то «да» и «нет».
/* modParser */
[[!mFilter2?
&filters=`isfolder:boolean`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'filters' => 'isfolder:boolean'
])}
parents, categories и grandparents
Следующие три фильтра применяются только к полю parent ресурса. Parents выводит имена двух родителей, через разделитель. Он включен по умолчанию.
/* modParser */
[[!mFilter2?
&filters=`parent:parents`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'filters' => 'parent:parents'
])}
Categories выводит имя непосредственного родителя.
/* modParser */
[[!mFilter2?
&filters=`parent:categories`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'filters' => 'parent:categories'
])}
Grandparents выводит имена родителей-дедушек и предназначен для больших каталогов. Если «дедушки» нет, то будет выведен непосредственный родитель.
/* modParser */
[[!mFilter2?
&filters=`parent:grandparents`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'filters' => 'parent:grandparents'
])}
vendors
Фильтр для вывода имён производителей товаров miniShop2. Применяется только к полю vendor
таблицы ms
.
/* modParser */
[[!mFilter2?
&where=`{"class_key":"msProduct"}`
&filters=`ms|vendor:vendors`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'where' => '{"class_key:=": "modDocument"}',
'filters' => 'ms|vendor:vendors'
])}
fullname
Этот фильтр выводит полное имя пользователя. Может применяться к любому полю, содержащему id юзера.
/* modParser */
[[!mFilter2?
&filters=`createdby:fullname`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'filters' => 'createdby:fullname'
])}
year
Этот фильтр применяется к полям с датой и выводит год. Можно, например, фильтровать новости по году создания.
/* modParser */
[[!mFilter2?
&filters=`createdon:year`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'filters' => 'createdon:year'
])}
month
Этот фильтр применяется к полям с датой и выводит месяц прописью, подставляя его название из словаря компонента.
day
Этот фильтр применяется к полям с датой и выводит день.
Псевдонимы фильтров
В последних версиях дополнения введена специальная система псевдонимов для фильтров, чтобы сделать их использование более удобным.
Вы можете указать список замены длинных названий фильтров на более короткие и понятные. Например:
В результате, url будут вот такие:
/* modParser */
[[!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`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'parents' => 0,
'element' => 'msProducts',
'aliases' => 'ms|price==price,resource|parent==parent',
'filters' => 'ms|price:number,parent:parents,parent:categories',
'class' => 'msProduct',
'filters' => 'createdon:year',
'tplFilter.outer.price' => 'tpl.mFilter2.filter.slider',
'tplFilter.row.price' => 'tpl.mFilter2.filter.number',
])}
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. Например, для фильтрации тикетов:
/* modParser */
[[!mFilter2?
&parents=`0`
&class=`Ticket`
&element=`getTickets`
&sortAliases=`{"ticket":"Ticket"}`
&sort=`ticket|createdon:desc,ticket|pagetitle:asc`
&showLog=`1`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'parents' => 0,
'class' => 'Ticket',
'sortAliases' => ['ticket' => 'Ticket'],
'sort' => 'ticket|createdon:desc,ticket|pagetitle:asc',
'showLog' => '1',
])}
Еще пример — сортировка по опции товара miniShop2:
/* modParser */
[[!mFilter2?
&parents=`0`
&element=`msProducts`
&leftJoin=`{
"Test1": {
"class": "msProductOption",
"on": "Test1.key = 'test1' and Test1.product_id = msProduct.id"
}
}`
&sortAliases=`{"test1":"Test1"}`
&aliases=`test1|value==test1`
&sort=`test1:desc`
]]
/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'parents' => 0,
'element' => 'msProducts,
'leftJoin' => '{"Test1":{"class":"msProductOption","on":"Test1.key=test1 and Test1.product_id = msProduct.id"}}',
'sortAliases' => ['test1' => 'Test1'],
'aliases' => 'test1|value==test1',
'sort' => 'test1:desc'
])}
Присоединяем опцию test1, добавляем для этой таблицы псевдоним и сортируем по значению присоединённой опции.
Ссылка для сортировки в чанке tpl.mFilter2.outer
в данном случае должна быть примерно такой:
/* modParser */
<a href="#" data-sort="test1"
data-dir="[[+mse2_sort:is=``:then=`desc`]]"
data-default="desc" class="sort">Test1 <span></span>
</a>
/* pdoParser */
<a href="#" data-sort="test1"
data-dir="{if !$mse2_sort ?}desc{/if}"
data-default="desc" class="sort">Test1 <span></span>
</a>
Обратите внимание, что указание псевдонима в &aliases даёт нам возможность сортировать по test1
, вместо test1|value
.
Если вам понадобится сортировать более чем по одной опции, то все их нужно подключить в выборку под своими уникальными псевдонимами и указать соответствующие ссылки.
Javascript
Вся работа фильтров обеспечивается скриптом default.js, который идёт в комплекте. Путь к нему указывается в системной настройке mse2_frontend_js
, так что, если вы захотите внести изменения, просто переименуйте этот файл и укажите новое название в настройке — чтобы при обновлении дополнения он не был перезаписан.
mSearch2.submit();
А сбросить значения так:
mSearch2.reset();
При обновлении фильтров срабатывает событие mse2_load:
$(document).on('mse2_load', function(e, data) {
console.log(e, data);
});
Вы можете использовать это событие для дополнительной обработки значений фильтра.
Лексиконы
Для оформления фильтров используются записи из лексикона. Если вы добавили новый фильтр и он отображается непонятной длинной надписью на английском — это значит, что её нужно добавить в словарь mSearch2.
Время запросов: 0,1215 s
Количество запросов: 27
Источник: cache