Дата публикации
10 Июня 2019
Дата изменения
30 Апреля 2021
Уникальных просмотров
7.542

Оглавление

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

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

Пример сниппета mFilter2

Параметры

Название По умолчанию Описание
&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.

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

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

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

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

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

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

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

Также вы можете менять переменные стандартного фильтра, указав их в виде 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"}
])}

После включения этой опции, в форме по умолчанию появится кнопка «Отправить» и для применения фильтров, нужно будет нажимать на неё.

Особенности

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

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

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

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

/* pdoParser */
{$_modx->runSnippet('!mFilter2', [
'paginator' => 'getPage',
'element' => 'mSearch2'
])}

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

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

/* 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. А если вы не указываете фильтр, то будет использован 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`

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

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

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

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

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

Функция безусловно приятная и полезная, но очень тяжелая для работы. Она напрямую зависит от количества фильтруемых результатов и параметров фильтров — то есть, сделать так, чтобы она не тормозила вообще нигде, невозможно. Поэтому она отключается автоматически для больших каталогов регулируемыми параметрами &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(), который вы можете изменить, как и все остальные.

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

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

`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
Время запросов: 0,1215 s
Количество запросов: 27
Источник: cache