Приветствую, друзья! Сегодня мы научимся создавать фильтр ресурсов в MODx Revolution с возможностью сортировки по любому TV полю и подгрузкой результатов по клику "Загрузить еще". Для вывода результатов будем использовать сниппет pdoResources.
Класснуть
Запинить
Скачать все сниппеты и необходимые файлы урока.
Для начала необходимо установить пакет pdoResources , который входит в состав пакета pdoTools . Вы можете установить или весь набор пакетов pdo (pdoTools) или только pdoResources отдельным пакетом для создания фильтра на MODx Revolution.
После установки пакетов, давайте подключим сниппет, который вы скачали в ваш проект. Если вы разрабатываете каталог сейчас с нуля, то советую придерживаться использования определенных классов для Ajax фильтрации. Схема именования классов:
Однако если у вас уже готовый каталог, вы можете определить классы элементов Ajax фиьтра в JS файле (см. ниже).
Обратите внимание, что .ajax-item должен быть непосредственным потомком .ajax-container . Если вы используете сетку Bootstrap для разметки колонок, можете определить класс контейнера как "row ajax-container" , а колонки айтема как "col-md-4 ajax-item" .
Подключение JS скрипта Ajax фильтра
Подключим скрипт JS к проекту. Вы можете подключить его как отдельным файлом, так и непосредственно в файл кастомных скриптов проекта. Для работы скрипта требуется jQuery.
$(function() { //MODx pdoResources Ajax Filter //Filter Settings var fadeSpeed = 200, // Fade Animation Speed ajaxCountSelector = ".ajax-count", // CSS Selector of Items Counter ajaxContainerSelector = ".ajax-container", // CSS Selector of Ajax Container ajaxItemSelector = ".ajax-item", // CSS Selector of Ajax Item ajaxFormSelector = ".ajax-form", // CSS Selector of Ajax Filter Form ajaxFormButtonStart = ".ajax-start", // CSS Selector of Button Start Filtering ajaxFormButtonReset = ".ajax-reset", // CSS Selector of Button Reset Ajax Form sortDownText = "По убыванию", sortUpText = "По возрастанию"; function ajaxCount() { if($(".ajax-filter-count").length) { var count = $(".ajax-filter-count").data("count"); $(ajaxCountSelector).text(count); } else { $(ajaxCountSelector).text($(ajaxItemSelector).length); } }ajaxCount(); function ajaxMainFunction() { $.ajax({ data: $(ajaxFormSelector).serialize() }).done(function(response) { var $response = $(response); $(ajaxContainerSelector).fadeOut(fadeSpeed); setTimeout(function() { $(ajaxContainerSelector).html($response.find(ajaxContainerSelector).html()).fadeIn(fadeSpeed); ajaxCount(); }, fadeSpeed); }); } $(ajaxContainerSelector).on("click", ".ajax-more", function(e) { e.preventDefault(); var offset = $(ajaxItemSelector).length; $.ajax({ data: $(ajaxFormSelector).serialize()+"&offset="+offset }).done(function(response) { $(".ajax-more").remove(); var $response = $(response); $response.find(ajaxItemSelector).hide(); $(ajaxContainerSelector).append($response.find(ajaxContainerSelector).html()); $(ajaxItemSelector).fadeIn(); }); }) $(ajaxFormButtonStart).click(function(e) { e.preventDefault(); ajaxMainFunction(); }) $(ajaxFormButtonReset).click(function(e) { e.preventDefault(); $(ajaxFormSelector).trigger("reset"); $("input").val("pagetitle"); $("input").val("asc"); setTimeout(function() { $("").data("sort-dir", "asc").toggleClass("button-sort-asc").text(sortUpText); }, fadeSpeed); ajaxMainFunction(); ajaxCount(); }) $(""+ajaxFormSelector+" input").change(function() { ajaxMainFunction(); }) $("").data("sort-dir", "asc").click(function() { var ths = $(this); $("input").val($(this).data("sort-by")); $("input").val($(this).data("sort-dir")); setTimeout(function() { $("").not(this).toggleClass("button-sort-asc").text(sortUpText); ths.data("sort-dir") == "asc" ? ths.data("sort-dir", "desc").text(sortDownText) : ths.data("sort-dir", "asc").text(sortUpText); $(this).toggleClass("button-sort-asc"); }, fadeSpeed); ajaxMainFunction(); }); });
- Строки 5-13: определение переменных для CSS селекторов Ajax фильтра. Не меняем, если используем стандартные значения, как на рисунке выше;
- Строки 15-22: скрипт счетчика ресурсов в результатах фильтрации;
- Строки 24-35: основная функция Ajax фильтрации;
- Строки 37-49: обработчик события по клику на кнопку "Загрузить еще";
- Строки 51-54: обработчик события по клику на кнопке "фильтровать". Данная кнопка может отсутствовать, так как фильтрация происходит автоматически. Автоматическая фильтрация может быть отключена путем удаления строк 68-70;
- Строки 56-66: обработчик события очистки формы и сброса фильтра. Строки 59-63 отвечают за сброс параметров сортировки;
- Строки 68-70: функция автоматической сортировки при изменении полей формы фильтра;
- Строки 72-82: универсальная функция сортировки по tv параметру.
Я постарался сделать данный скрипт максимально универсальным, поэтому если вы используете стандартные селекторы элементов Ajax фильтра, то редактировать ни чего не нужно.
Подключение PHP сниппета в MODx Revolution
Создайте новый сниппет в панели управления MODx catalogFilter и заполните его следующим содержимым:
=".$_GET["area_from"]; } if($_GET["area_to"]) { $filter = "area<=".$_GET["area_to"]; } //Checkbox Type if($_GET["garage"]) { $filter = "garage=1"; } //End Settings //Sort if($_GET["sortby"]) { $sortby = $_GET["sortby"]; } else { $sortby = "pagetitle"; } if($_GET["sortdir"]) { $sortdir = $_GET["sortdir"]; } else { $sortdir = "asc"; } //End Sort //Offset $offset = 0; if($_GET["offset"]){ $offset = $_GET["offset"]; } if($filter) { $where = $modx->toJSON(array($filter)); } else { $where = ""; } $params_count = array("parents" => $parents, "limit" => 0, "tpl" => "@INLINE ,", "select" => "id", "includeTVs" => $fields, "showHidden" => "1", "where" => $where); $count = $modx->runSnippet("pdoResources",$params_count); $count = count(explode(",",$count))-1; $modx->setPlaceholder("count",$count); $params = array("parents" => $parents, "limit" => $limit, "offset" => $offset, "tpl" => $tpl, "select" => "id,pagetitle,introtext,content", "includeTVs" => $fields, "showHidden" => "1", "sortby" => $sortby, "sortdir" => $sortdir, "where" => $where); $more = $count - $offset - $limit; $lim = $more > $limit ? $limit: $more; $button = ""; if($more > 0){ $button = "Между комментариями //Filter Fields Settings и //End Settings находятся параметры, которые вам необходимо отредактировать под свой проект. Тут ни чего сложного, просто прописываете name полей input и проверяете их условием if. Для полей типа Radio, Select и Text используем пример из строк 5-8. Для определения промежуточного значения от и до можно воспользоваться примером из строк 11-16. Для чекбоксов подойдет пример из строк 19-21.
В строке 74 сниппета вы можете задать свои классы, но не удаляйте текущюю разметку, так как она учавствует в скриптах для подгрузки контента.
Пример возможных значений в панели управления MODx для радиокнопок: Первый==1||Второй==2||Третий==3
Пример вывода радиокнопок во фронтенд:
Здесь именование name="floor" соответствует строкам 6-8 нашего сниппета catalogFilter . Аналогично реализована обработка других полей формы. Я думаю, это понятно и создание своих собственных полей не будет для вас проблемой.
Вывод сниппета осуществляется в шаблоне каталога следующим образом:
[[!catalogFilter? &tpl=`tplCatItem` &limit=`3` &parents=`5` &fields=`image,area,floor,garage,price`]]
- tpl=`tplCatItem` - чанк айтема в списке каталога;
- limit=`3` - Сколько записей выводить и по сколько записей подгружать при клике на кнопке "Загрузить еще";
- parents=`5` - указываем id роительского документа для каталога ресурсов;
- fields=`image,area,floor,garage,price` - перечисляем TV"s, которые необходимо показать в чанке tplCatItem и которые необходимо обрабатывать при фильтрации.
Пример чанка tplCatItem
[[+pagetitle]]
Этаж | [[+tv.floor]] |
Площадь | [[+tv.area]] кв.м. |
Гараж | [[+tv.garage:is=`1`:then=`Есть`:else=`Нет`]] |
Цена: | [[+tv.price]] |
Комплексный пример вывода во фронтенд можете посмотреть в репозитории проекта на гитхабе в файле demo.html .
Ajax сортировка по TV
В нашем скрипте имеется готовое решение для сортировки результатов фильтрации по любому TV полю. В форму фильтра вставьте следующие скрытые поля и не меняйте их значение, они просто должны быть в форме фильтра:
В любом месте вашего HTML шаблона сделайте вывод кнопки и в data атрибуте укажите поле, по которому хотите фильтровать выдачу:
Сортировать по цене: По возрастанию
При клике тогглится класс button-sort-asc , который можете использовать для оформления кнопки при смене направления сортировки, добавления стрелочек и т. д. в атрибут data-sort-by можно писать любой TV, учавствующий в фильтрации. С сортировкой все.
Итак, мы рассмотрели создание несложного Ajax фильтра ресурсов в MODx с выводом результатов в сниппет pdoResources .
Фильтры в революции позволяют управлять способом представления данных. Они позволяют изменять значения внутри шаблонов.
В революции выходной фильтр применяется один или более раз из серии выходных модификаторов, которые ведут себя подобно PHx вызывам в MODx Evolution - за исключением, что они встроены в ядро. Синтаксис выглядит следующим образом:
[ ]
Они также могут быть соединены (выполняется слева направо):
[ ]
Вы также можете использовать их, чтобы изменить выход сниппета; внимание, модификатор идет после имени сниппета и перед вопросительным знаком, например,
[ ]
В следующей таблице перечислены некоторые из существующих модификаторов и приведены примеры их использования. Хотя приведенные ниже примеры являются для некоторых тегов, выходные модификаторы могут быть использованы с любым тегом MODx. Убедитесь, что модификатор получает данные.
Условные модификаторы:
Модификатор |
Описание |
Пример |
if, input |
||
Логическое ИЛИ |
[ [+numbooks:is=`5`:or:is=`6`:then=`There are 5 or 6 books!`:else=`Not sure how many books`] ] |
|
Логическое И |
||
isequalto, isequal, equalto, equals, is, eq |
[ [+numbooks:isequalto=`5`:then=`There are 5 books!`:else=`Not sure how many books`] ] |
|
notequalto, notequals, isnt, isnot, neq, ne |
[ [+numbooks:notequalto=`5`:then=`Not sure how many books`:else=`There are 5 books!`] ] |
|
greaterthanorequalto, equalorgreaterthen, ge, eg, isgte, gte |
Больше или равно |
[ [+numbooks:gte=`5`:then=`There are 5 books or more than 5 books`:else=`There are less than 5 books`] ] |
isgreaterthan, greaterthan, isgt, gt |
[ [+numbooks:gt=`5`:then=`There are more than 5 books`:else=`There are less than 5 books`] ] |
|
equaltoorlessthan, lessthanorequalto, el, le, islte, lte |
Меньше или равно |
[ [+numbooks:lte=`5`:then=`There are 5 or less than 5 books`:else=`There are more than 5 books`] ] |
islowerthan, islessthan, lowerthan, lessthan, islt, lt |
[ [+numbooks:lt=`5`:then=`There are less than 5 books`:else=`There are more than 5 books`] ] |
|
[ [+numbooks:lt=`1`:hide] ] |
||
[ [+numbooks:gt=`0`:show] ] |
||
[ [+numbooks:gt=`0`:then=`Now available!`] ] |
||
[ [+numbooks:gt=`0`:then=`Now available!`:else=`Sorry, currently sold out.`] ] |
||
memberof, ismember, mo |
[ [+modx.user.id:memberof=`Administrator`] ] |
Строковые модификаторы:
Модификатор |
Описание |
Пример |
Если не пусто |
[ [+numbooks:cat=` books`] ] |
|
lcase, lowercase, strtolower |
Транформация в малые буквы |
[ [+title:lcase] ] |
ucase, uppercase, strtoupper |
Трансформация в большие буквы |
[ [+headline:ucase] ] |
Первая буква слова заглавная |
[ [+title:ucwords] ] |
|
Первая буква заглавная |
[ [+name:ucfirst] ] |
|
htmlent, htmlentities |
Замена тегов HTML |
[ [+email:htmlent] ] |
esc,escape |
Безопасно убирает символы |
[ [+email:escape] ] |
Замена перевода каретки, табуляции и множества пробелов на один пробел |
[ [+textdocument:strip] ] |
|
stripString |
Удаляет значение из строки |
[ [+name:stripString=`Mr.`] ] |
Замена значения |
[ [+pagetitle:replace=`Mr.==Mrs.`] ] |
|
striptags, stripTags,notags,strip_tags |
Убирает HTML теги |
[ [+code:strip_tags=` |
len,length, strlen |
Длина строки |
[ [+longstring:strlen] ] |
reverse, strrev |
Реверс строки |
[ [+mirrortext:reverse] ] |
wordwrap |
Новая строка после указанного количества символов |
[ [+bodytext:wordwrap=`80`] ] |
wordwrapcut |
Вставляет символ новой строки после определенного количества символов. |
[ [+bodytext:wordwrapcut=`80`] ] |
Выводимое кол-во символов |
[ [+description:limit=`50`] ] |
|
ellipsis |
Обрезание строки после указанного кол-ва символов |
[ [+description:ellipsis=`50`] ] |
Отображает сырой элемент без: тега. Полезно для документации. |
[ [+showThis:tag] ] |
Если значение может изменяться динамически, то его следует сделать некэшированным. Например:
[ [+placeholder:default=`A default value!`] ]
Это означает, что значение может иногда быть пустым, а иногда нет. Зачем его хранить в кэше? Это может исключить то, что значение может появиться.
Если вы не уверены будет ли результат при выполнении сниппета, то логично сделать значение по умолчанию:
[ [!getResources:default=`Sorry - nothing matched your search.`? &tplFirst=`blogTpl` &parents=`2,3,4,8` &tvFilters=`blog_tags==%%` &includeTVs=`1`] ]
PHx (Placeholders Xtended) добавляет новые возможности для отображения плейсхолдеров, тегов MODx (включая TV параметры) и теги настроек сайта. Рекурсивный парсер позволяет использовать вложенные теги. Возможно создавать свои модификаторы, путем создания сниппетов.
Скачать последнюю версию PHx из репозитория MODX можно по этой ссылке .
Новая установка
- Скачайте и распакуйте архив.
Обновление
- Скачайте и распакуйте архив.
- Переименуйте директорию /assets/plugins/phx в /assets/plugins/phx-old
- Создайте директорию "phx" в папке /assets/plugins.
- Закачайте через FTP или просто скопируйте содержимое архива в /assets/plugins/phx
- Создайте новый плагин "PHx" в Панели управления MODx (Элементы-Управление элементами-Плагины) и скопируйте в него содержимое файла phx.plugin.txt
- Отметьте событие "OnParseDocument" на вкладке "Системные события"
Конфигурация
На вкладке конфигурация, во время редактирования плагина скопируйте в поле "Конфигурация плагина":
&phxdebug=Лог событий;int;0 &phxmaxpass=Макс. число проходов;int;50
Для опытных пользователей
Вы можете изменить настройки по умолчанию для плагина PHx:
Лог событий
0 = Отключен
1 = Включено логирование событий PHx
Если включено PHx создает подробный лог на каждое событие, записанное в протоколе событий (Отчеты->Просмотр событий)
Макс. число проходов
Определяет максимально обрабатываемую глубину вложенных тегов. Рекомендуется оставить значение 50.
PHx (Placeholders Xtended) расширяет возможности использования плейсхолдеров, тегов содержимого (включая TV параметры) и тегов настройки сайта. Благодаря этому вы можете с легкостью определять формат вывода конечного результата. PHx встраивается в парсер MODX, расширяя его функционал модификаторами, условиями и в качестве бонуса делает его по-настоящему рекурсивным.
Поддерживаемые теги
PHx поддерживает следующие теги MODx:
- [+placeholder+]
- [*теги содержимого*] (например: [*content*], [*pagetitle*] и другие)
- [*TV параметры*]
- [(теги настройки)] (например: [(base_url)], [(site_name)] и другие)
Сниппеты, поддерживающие PHx
- Ditto
- MaxiGallery
Вы можете использовать PHx синтаксис в чанках, используемых сниппетами не из этого списка, но для этого требуется другой метод (см. раздел Tips & Tricks)
Обычный плейсхолдер вида
[+placeholder+]
легко превращается в плейсхолдер PHx:
[+placeholder:esc+]
Тоже самое вы можете сделать с тегом содержимого:
[*createdby*]
Добавляем модификатор:
[*createdby:date=`%a %B %d, %Y at %H:%M`*]
Также можно использовать несколько модификаторов сразу. Они будут обработаны слева направо:
Somevar:esc:nl2br:strip
Расширенное применение
Наличие специального плейсхолдера "phx" позволяет использовать синтаксис PHx без наличия реальной переменной.
[+phx:if=`[+this+]`:is=`[+that+]`:then=`do this`:else=`do that`+]
С некоторыми модифиакторами этот плейсхолдер приобретает определенное значение. В случае с модификатором "userinfo" он возвращает соответствующее значение из информации о текущем пользователе:
[+phx:userinfo=`username`+]
Известные проблемы
Синтаксис
Это кажется логичным, но на этом стоит заострить внимание. Избегайте использования следующих конструкций в шаблоне, если они не являются частью тега MODx:
[+[*
[(
+]
*]
)]
]]
Парсер попытается их обработать и MODx выдаст ошибку. Обычно такой проблемы не возникает. Но в случае с JavaScript у вас может быть конструкция, похожая на эту:
Array
Которая спровоцирует странное поведени из-за +]. Также закрывающий тег CDATA:
/* ]]> */
Может создать проблемы.
Помните, что вы не сможете потерять данные вашего сайта, используя неправильный синтаксис PHx. Худшее, что может случится - ваш шаблон неправильно отобразится.
Строки
lcase
ucase
Приведет все символы строки к верхнему регистру.
[+string:ucase+]
На входе:
This is a string
THIS IS A STRING
ucfirst
Первая буква в строке станет заглавной.
[+string:ucfirst+]
На входе:
length | len
Возвратит длину строки.
На входе:
This is a string
notags
Вырежет все HTML теги из строки.
[+string:notags+]
На входе:
This is a string
This is a string
esc
Удаляет html теги и разрывы строк
htmlent
Конвертирует исходную переменную в html сущности. Аналог htmlentities() в PHP.
nl2br
Конвертирует символы перевода строки в теги.
[+string:nl2br+]
На входе:
This is
a string
This is
a string
strip
Удалит символы новой строки(\n), табуляторы(\t), идущие подряд пробелы.
[+string:strip+]
На входе:
This is
a
string
This is a string
Другие модификаторы
reverse
Перевернет задом наоборот буквы.
wordwrap
Breaks words in the current value longer than the given length of characters by putting a space in between.
По умолчанию: 70 символов.
Wordwrap(=`length`)
length - символы
limit
Возвратит первые X символов от текущего значения.
По умолчанию: 100 символов.
limit(=`length`)
Специальные
date
Преобразует метку времени unix timestamps в соответствии с заданным форматом.
date(=`dateformat`)
dateformat: В соответствии с форматом PHP-функции strftime
[*createdon:date=`%d.%m.%Y`*]
Для того, чтобы дата выводилась в соответствии с текущим языком сайта, необходимо установить локаль в начале кода плагина PHx. Пример ниже для немецкого языка:
setlocale(LC_ALL, "de_DE@euro", "de_DE", "de", "ge");
md5
Создает MD5-хэш текущего значения.
userinfo
Поля, используемые в базе данных MODx из таблицы user_attributes (например: username, useremail).
Userinfo=`field`
- cachepwd : Cache password
- comment : Comment
- country : Страна
- dob : Дата рождения в формате времени UNIX
- email : Email
- fax : Факс
- fullname : Полное имя
- gender : Пол
- internalKey : User internal key
- lastlogin : Last login, in UNIX time format
- logincount : Number of logins
- mobilephone : Мобильный телефон
- password : Пароль
- phone : Телефон
- photo : Фотография
- role : Роль
- state : Статус
- thislogin : This login, in UNIX time format
- username : Логин
- zip : Почтовый индекс
math
Использовать вычисления, такие, как - * + /.
Math=`calculation`
"?" символ заменяется текущим значением расширения, но вы также можете использовать вложенные теги.
Пример расчета: ?+1+(2+3)+4/5*6
ifempty
Использовать "other value" если значение placeholder/templatevar пустое.
Ifempty=`other value`
select
Принимает значение, в зависимости от значений placeholder/templatevar.
Select=`options`
параметры: value1=output1&value2=output2
На входе: 1
[+placeholder:select=`0=OFF&1=ON&2=UNKNOWN`+]
Вернет: ON
Условные выражения
is
ne
alias: isnot, isnt
не равно (!=)
eg
больше или равно (>=)
el
меньше или равно (<=)
gt
больше (>)
lt
меньше (<)
mo=`Webgroups`
синонимы(алиасы): isinrole, ir, memberof
Принимает в качестве параметра разделенный запятыми список веб-групп и возвращает значение true/false в зависимости от того, принадлежит текущий пользователь к какой-либо из этих групп или нет (заменяет собой модификатор "inrole" , который необходимо было сочетать с условным оператором).
[+phx:mo=`myWebgroup`:then=`I"m a member`:else=`I"m NOT a member`+]
if =`value`
Принимает в качестве параметра переменную для сравнения. Также может быть использовано в сочетании с :or или :and .
[+phx:if=`[+price+]`:gt=`0`:then=`Цена: [+price+]`+]
or
Логическое ИЛИ (проверяется, верно ли первое или второе условие).
[+phx:if=`[*id*]`:is=`2`:or:is=`3`:then=`{{Chunk}}`:else=`{{OtherChunk}}`+]
В данном примере если текущий ID равен 2 или 3, то выводится чанк {{Chunk}}, иначе выводится чанк {{OtherChunk}}.
and
Логическое И (проверяется, верны ли оба условия).
[+phx:if=`[!UltimateParent!]`:is=`1`:and:isnot=`[*id*]`:then=`{{ChildChunk}}`:else=`{{ParentChunk}}`+]
В данном примере если UltimateParent равен 1 и при этом не равен текущему ID, то выводится чанк {{ChildChunk}}, иначе выводится чанк { {ParentChunk}}.
then =`template`
Значение template отображается, когда все условия верны. Здесь можно указать вызов {{чанка}}, [[сниппета]] или же чистый HTML.
else =`template`
Значение template отображается, когда условия не верны. Здесь можно указать вызов {{чанка}}, [[сниппета]] или же чистый HTML.
show
Используется подобно then , но в качестве шаблона для вывода используется исходное значение. Выполняется, если условия верны.
[+myplaceholder:len:gt=`3`:show+]
В данном примере значение плейсхолдера будет выведено, если его длина составляет более 3 символов.
Пользовательские модификаторы
Модификатор представляет собой простой сниппет, который обрабатывает заданное значение. Существует возможность создавать свои собственные модификаторы/мини-сниппеты, добавив новый сниппет в менеджере ресурсов MODx или же создав файл в папке модификаторов плагина PHx.
Поскольку код модификатора несложен, то ему не нужны никакие параметры, за исключением тех, которые он получает от парсера.
Существуют две основные переменные:
$output
- содержит текущее значение переменной, которую необходимо модифицировать.
$options
- необязательный параметр, значение которого передается в модификатор.
Пример.
Приведем пару примеров использования модификаторов. Допустим, что плейсхолдер myplaceholder имеет значение "test" :
[+myplaceholder:mymodifier+]
Переменная $output содержит значение "test".
Переменная $options не содержит ничего, т.к. модификатору не был передан параметр.
[+myplaceholder:mymodifier=`my options`+]
Переменная $output все еще содержит значение "test".
Переменная $options теперь содержит значение "my options"
Прочие переменные (для продвинутых пользователей)
$input - содержит исходное немодифицированное значение.
$condition - массив, содержащий элементы, образующие условное выражение (0, 1, || и &&).
Создание собственного модификатора
Пример 1: I love MODx
Используя полученные знания, создадим новый пользовательский модификатор. Это будет модификатор без параметра, который просто добавит текст " because I love MODx" к переменной. Для этого необходимо проделать следующие шаги:
1. В Менеджере ресурсов надо зайти в Ресурсы(Элементы) -> Управление ресурсами (элементами) -> Сниппеты
2. Нажать "Новый сниппет"
phx:love "
Для того, чтобы сниппет воспринимался как модификатор для PHx, его название должно иметь префикс "phx:" без пробелов между ним и собственно именем сниппета. Тогда можно будет его использовать как модификатор, добавив:love к любому плейсхолдеру, например: [+myplaceholder:love+].
4. Теперь добавим код модификатора в поле для кода. Допустим, это будет код следующего вида:
5. Сохраним изменения и наш новый модификатор (:love ) готов к использованию!
Пример 2: I love MODx even more
Создадим модификатор, подобный модификатору :love из предыдущего примера, но дополнительно дадим ему возможность добавлять к исходной строке значение переданного параметра, если оно было указано.
1. В Менеджере ресурсов надо зайти в Ресурсы(Элементы) -> Управление ресурсами (элементами) -> Сниппеты
2. Нажать "Новый сниппет"
3. В качестве имени сниппета задать "phx:love2 "
Для того, чтобы сниппет воспринимался как модификатор для PHx, его название должно иметь префикс "phx: " без пробелов между ним и собственно именем сниппета. Тогда можно будет его использовать как модификатор, добавив:love к любому плейсхолдеру, например: [+myplaceholder:love2+] .
ChunkGood .
Прочие примеры
[+myplaceholder:gt=`1`:then=`Yes`:else=`No`+]
[+myplaceholder:lt=`3`:and:gt=`1`:then=`Yes`:else=`No`+]
[+myplaceholder:lt=`[+someplaceholder+]`:then=`Yes`:else=`No`+]
[+myplaceholder:islt=`2`:then=`Yes`:else=`No`+]
[+myplaceholder:isnot=`2`:or:lt=`3`:then=`Yes`:else=`No`+]Все примеры вернут Yes .
[+myplaceholder:isnot=`2`:then=`Yes`:else=`No`+]
[+myplaceholder:gt=`[+someplaceholder+]`:then=`Yes`:else=`No`+]
[+myplaceholder:lt=`2`:then=`Yes`:else=`No`+]
[+myplaceholder:gt=`2`:then=`Yes`:else=`No`+]
[+myplaceholder:lt=`1`:then=`Yes`:else=`No`+]Все примеры вернут No .
Всем доброго здравия. В этой статье я расскажу как сделать фильтр документов по tv-параметрам на сайте под управлением Modx Revolution. Мы будем использовать сниппет tagManager2 от Аndchir . Этот сниппет умеет работать сразу с несколькими tv, а также с числовыми данными (в виде цены) и множественным списком. Каждый этот пример мы разберем далее.
1. Для начала нужно установить tagManager2
Для этого идем в Приложения/Установщик/
жмем кнопку «Загрузить дополнение» и в строке поиска вбиваем tagManager2
Также еще нужно установить сниппет getPage и getProducts . Таким образом раздел «Управление пакетами» должен выглядеть так (сниппет translit, кстати, отвечает за транслитерацию псевдонимов на латиницу)
Загружаем, устанавливаем пакеты и идем в «Настройки системы»
2. Настраиваем сниппет tagManager2
В Системных настройках выбираем раздел tag_manager2
Мы увидим параметры настройки фильтра
Там все достаточно просто и понятно, но все же:
- В «ID ресурса каталога верхнего уровня» указываете id шаблона каталога или категории, где будут фильтроваться товары или страницы
- В «Дополнительный разделитель множественного списка» ставим знак #. Ниже вы узнаете зачем он нужен
- В «Имена TV или полей с множественным списком» прописываем tv с множественным списком. Как их создать я покажу ниже
- «Имена TV или полей с числовыми значениями» - здесь нужно указать tv-параметры, в которых будут цифры. Обычно это параметр цены. Данный фильтр будет выведен в виде ползунка «от и до»
- В «ID шаблонов товаров» прописываем id страниц, которые нужно фильтровать и к которым прикреплены tv-параметры, указанные выше
- В «Имя набора параметров, используемого для фильтрации» прописываем catalog_filters. Данный шаблон мы будем использовать в шаблонах параметров getPage и getProducts
- Прописать в «Сниппет связанный с набором параметров» название сниппета, который будет осуществлять вывод и пагинацию страниц или товаров. Обычно это getPage .
3. Создаем набор параметров catalog_filters в getPage
Идем в сниппет getPage
Переходим во вкладку «Параметры» и нажимаем на кнопку «Добавить набор параметров» . Можно конечно и отредактировать существующий, но тогда есть шанс затирания параметров, которые мы сейчас создадим при обновлении getPage. Если не собираетесь обновлять можете просто редактировать.
Редактируем существующие параметры и присваиваем значения:
Создаем новые параметры и присваиваем значения
Отредактированные параметры будут отображаться зеленым цветом, созданные - фиолетовым
4. Создаем или редактируем tv параметры для фильтра
Я создал для примера 3 tv-параметра
Особое внимание хочу привлечь к тому, что нужно указывать Имя (Заголовок) tv-параметра, а иначе он может просто не отображаться в модуле управления фильтрами
5.Создаем чанк filtr_tpl
Этот чанк отвечает за вывод каждого отдельно результата в getProducts
6. Создаем структуру в дереве документов
У меня она выглядит так:
Главная страница у нас с ID 1, а у товаров id шаблона 1 (это у нас стоит в настройках tag_manager2, если у Вас другие значения, не забудьте поменять в настройках)
7. Редактируем filters.js
Идем по адресу /assets/components/tag_manager2/js/web/filters.js и вместо
Multitags: ["tags"],//Имена доп. полей с множественными значениями
вставляем код с нашими подставленными значениями
Multitags: ["filtr1", "filtr2"],//Имена доп. полей с множественными значениями
Здесь все предельно просто и понятно. Мы вставили свои tv-поля с множественными значениями. А вообще это конфиг всех настроек (но лучше без разрешения больших дяденек их не трогать, я имею ввиду советов создателей модуля)
8. Выводим фильтр и результаты фильтрации
Сам фильтр
[]Вывод результатов с пагинацией
-
[[!+page.nav]]
Сортировка результатов
9. Активируем фильтр
Теперь нужно лишь активировать наш фильтр. Для этого идем в Приложения/Управление фильтрами .
Здесь нужно поставить галочки возле каждого фильтра и нажать кнопку «Сохранить» .
Если вы все сделали правильно, то фильтр должен заработать. На этом все. Если появились вопросы - задавайте в комментариях, постараюсь ответить. А вообще вот документация по tagManager2 . Успехов в разработке. В "Демо" один из моих сайтов, на котором реализован фильтр с помощью tagManager2
Фильтры в Revolution позволяют обрабатывать и изменять значения тегов внутри ваших шаблонов, чанков, сниппетов.
Фильтры ввода
В настоящее время фильтры ввода используются при подготовке к обработке фильтров вывода. Обычно они используются только внутри ядра MODX.
Фильтры вывода
В MODX Revolution фильтры вывода используются как один или нескольких модификаторов вывода, они схожи с PHx вызовами в MODx Evolution, но отличаются тем, что уже изначально встроены в ядро.
Синтаксис модификаторов:
[[+element:modifier=`value`]]
Фильтры могут применяться последовательно (пишутся слева направо):
[[+element:modifier=`value`:anothermodifier=`value2`:andanothermodifier:yetanother=`value3`]]
Также фильтры могут применяться для модификации вывода сниппетов . Фильтр нужно прописывать перед всеми параметрами (перед знаком вопроса):
Модификаторы вывода
В таблице представлены некоторые модификаторы и примеры их использования. В примерах они применяются к плейсхолдерам, но вы должны помнить, что модификаторы могут применяться к любым тегам MODX Revolution .
Модификатор | Описание | Пример использования |
if, input | if - задает дополнительное условие, input - добавляет в тег обрабатываемые данные | [[+num:is=`10`:and:if=`[[+num]]`:ne=`15`:then=`Да, равно 10 и не 15`]] |
or, and | Объединение нескольких модификаторов связью ИЛИ, и связью И | [[+numProducts:is=`10`:or:is=`11`:then=`Здесь 10 или 11 товаров`:else=`Не уверен, сколько товаров`]] |
isequalto, isequal, equalto, equals, is, eq | Сравнивает передаваемое значение с установленным. Если значения совпадают, выводится значение "then", если нет - "else" | [[+numProducts:isequalto=`10`:then=`Здесь 10 товаров`:else=`Не уверен, сколько товаров`]] |
notequalto, notequals, isnt, isnot, neq, ne | Сравнивает передаваемое значение с установленным. Если значения НЕ совпадают, выводится значение "then", если нет - "else" | [[+numProducts:notequalto=`10`:then=`Не уверен, сколько товаров`:else=`Здесь 10 товаров`]] |
greaterthanorequalto, equalorgreaterthen, ge, eg, isgte, gte | То же, только условие "Больше или равно" | [[+numProducts:gte=`10`:then=`Здесь 10 товаров или больше`:else=`Здесь меньше 10 товаров`]] |
isgreaterthan, greaterthan, isgt, gt | То же, только условие "Строго больше" | [[+numProducts:gt=`10`:then=`Здесь больше 10 товаров`:else=`Здесь 10 товаров или меньше`]] |
equaltoorlessthan, lessthanorequalto, el, le, islte, lte | То же, только условие "Меньше или равно" | [[+numProducts:lte=`10`:then=`Здесь 10 товаров или меньше`:else=`Здесь больше 10 товаров`]] |
islowerthan, islessthan, lowerthan, lessthan, islt, lt | То же, только условие "Строго меньше" | [[+numProducts:lte=`10`:then=`Здесь меньше 10 товаров`:else=`Здесь 10 товаров или больше`]] |
hide | Скрывает элемент, если условие выполняется | [[+numProducts:lt=`1`:hide]] |
show | Отображает элемент, если условие выполняется | [[+numProducts:gt=`0`:show]] |
then | Используется для составления условий | [[+numProducts:gt=`0`:then=`Товары в наличии!`]] |
else | Используется для составления условий (совместно с "then") | [[+numProducts:gt=`0`:then=`Товары в наличии!`:else=`Простите, но все продано.`]] |
memberof, ismember, mo | Проверяет, является ли пользователь членом указанной группы пользователей | [[+modx.user.id:memberof=`Administrator`]] |
Модификаторы для работы со строками
Модификатор | Описание | Пример использования |
cat | Добавляет значение после тега | [[+numProducts:cat=` товаров`]] |
lcase, lowercase, strtolower | Переводит все буквы в нижний регистр | [[+title:lcase]] |
ucase, uppercase, strtoupper | Переводит все буквы в верхний регистр | [[+longtitle:ucase]] |
ucwords | Делает первую букву в словах заглавной | [[+title:ucwords]] |
ucfirst | Делает первую букву в строке заглавной | [[+name:ucfirst]] |
htmlent, htmlentities | Преобразует все символы в HTML-сущности | [[+email:htmlent]] |
esc, escape | Безопасно экранирует символы, используя регулярные выражения и str_replace . Также экранирует символы [, ] и ` | [[+email:escape]] |
strip | Заменяет все переносы, табуляции и любое количество пробелов только одним пробелом | [[+textdocument:strip]] |
stripString | Вырезает из строки указанную подстроку | [[+name:stripString=`Mr.`]] |
replace | Производит замену подстрок | [[+pagetitle:replace=`Mr.==Mrs.`]] |
striptags, stripTags, notags, strip_tags | Вырезает все теги (можно указать разрешенные теги). | [[+code:strip_tags=` |
len, length, strlen | Выводит длину строки | [[+longstring:strlen]] |
reverse, strrev | Переворачивает строку символ за символом | [[+mirrortext:reverse]] |
wordwrap | Вставляет перенос строки после каждого n-ого символа (слова не разбиваются) | [[+bodytext:wordwrap=`80`]] |
wordwrapcut | Вставляет перенос строки после каждого n-ого символа, даже если этот символ будет внутри слова | [[+bodytext:wordwrapcut=`80`]] |
limit | Выводит определенное количество символов с начала строки (значение по умолчанию - 100) | [[+description:limit=`50`]] |
ellipsis | Добавляет многоточие и обрезает строку, если она длиннее, чем определенное количество символов (значение по умолчанию - 100) | [[+description:ellipsis=`50`]] |
tag | Экранирование. Отображает элемент так как он есть, без:tag. Для использования в документации | [[+showThis:tag]] |
math | Возвращает результат продвинутых вычислений (нагружает на процессор. Не рекомендуется) | |
add, increment, incr | Прибавляет указанное число (значение по умолчанию +1) | [[+downloads:incr]], [[+blackjack:add=`21`]] |
subtract, decrement, decr | Вычитает указанное число (значение по умолчанию -1) | [[+countdown:decr]], [[+moneys:subtract=`100`]] |
multiply, mpy | Умножает на указанное число (значение по умолчанию *2) | [[+trifecta:mpy=`3`]] |
divide, div | Делит на указанное число (значение по умолчанию /2) | [[+rating:div=`4`]] |
modulus, mod | Возвращает деление числа по модулю (по-умолчанию: %2, возвращает 0 или 1)) |
[[+number:mod]] |
ifempty, default, empty, isempty | Возвращает значение модификатора, если значение тега пусто | [[+name:default=`anonymous`]] |
notempty, !empty, ifnotempty, isnotempty | Возвращает значение модификатора, если значение тега НЕ пусто | [[+name:notempty=`Привет, [[+name]]!`]] |
nl2br | Заменяет символы новой строки (\n) на HTML-тег |
[[+textfile:nl2br]] |
date | Переводит таймстамп в текст, в соответствии с указанным форматом (Формат даты) | [[+birthyear:date=`%Y`]] |
strtotime | Переводит дату в виде текста в UNIX таймстамп | [[+thetime:strtotime]] |
fuzzydate | Возвращает дату в формате "вчера, сегодня, …". Принимает значение даты. | [[+createdon:fuzzydate]] |
ago | Возвращает число секунд, минут, недель или месяцев, прошедших с даты, указанной в теге. | [[+createdon:ago]] |
md5 | Создает MD5-хеш значения | [[+password:md5]] |
cdata | Оборачивает вывод тегами CDATA | [[+content:cdata]] |
userinfo | Возвращает запрашиваемое значение из профиля пользователя. Необходимо указывать ID пользователя | [[+modx.user.id:userinfo=`username`]] |
isloggedin | Возвращает true, если пользователь аутентифицирован в текущем контексте | [[+modx.user.id:isloggedin]] |
isnotloggedin | Возвращает true, если пользователь НЕаутентифицирован в текущем контексте | [[+modx.user.id:isnotloggedin]] |
urlencode | Конвертирует значение в URL | [[+mystring:urlencode]] |
urldecode | Конвертирует значение из URL | [[+myparam:urldecode]] |
Использование модификаторов вывода совместно с параметрами
Если у тега есть параметры, то их необходимо прописывать сразу после модификатора:
Создание пользовательского модификатора
Любой сниппет может использоваться и как модификатор вывода. Для его использования просто укажите имя сниппета вместо модификатора. К примеру, создадим сниппет makeExciting, добавляющий к выводу определенное количество восклицательных знаков:
[[*pagetitle:makeExciting=`4`]]
Такой вызов тега передаст в сниппет makeExciting следующие параметры для обработки:
Модификатор UserInfo
Прямой доступ к данным из таблицы modx_user_attributes в базе данных, с помощью модификаторов вывода вместо сниппетов, может быть достигнуто просто за счет использования модификатора UserInfo.
Выберите нужный столбец из таблицы и укажите его в качестве свойства модификатора, например, так:
Значение | Модификатор |
Внутренний ключ пользователя | [[!+modx.user.id:userinfo=`internalKey`]] |
Логин | [[!+modx.user.id:userinfo=`username`]] |
Полное имя | [[!+modx.user.id:userinfo=`fullname`]] |
Роль | [[!+modx.user.id:userinfo=`role`]] |
[[!+modx.user.id:userinfo=`email`]] | |
Телефон | [[!+modx.user.id:userinfo=`phone`]] |
Мобильный телефон | [[!+modx.user.id:userinfo=`mobilephone`]] |
Факс | [[!+modx.user.id:userinfo=`fax`]] |
Дата рождения | [[!+modx.user.id:userinfo=`dob`:date=`%Y-%m-%d`]] |
Пол | [[!+modx.user.id:userinfo=`gender`]] |
Страна | [[+modx.user.id:userinfo=`country`]] |
Область | [[+modx.user.id:userinfo=`state`]] |
Почтовый индекс | [[+modx.user.id:userinfo=`zip`]] |
Фото | [[+modx.user.id:userinfo=`photo`]] |