Создание пользовательского сниппета
Шаблонизация сниппетов в MODx Revolution
Одной из самых лучших практик , это когда вы никогда прямо не пишете HTML код в сниппете, но вставляете HTML код для шаблонизации сниппета в чанки. Этот урок покажет вам как сделать это в сниппете.
Наш начальный сниппет
Давайте разберём пример, где вам нужно пройти через опубликованные неудалённые ресурсы, которые являются наследниками Ресурса с ID 390, отсортированного по и далее вывести их в тегах LI с именем статьи pagetitle и активной ссылкой.
Давайте продолжим и создадим сниппет с именем 'ResourceLister' и вставим следующий код:
/* первое, постройте запрос */
$c = $modx->newQuery('modResource');
/* нам нужны только опубликованные и неудалённые ресурсы */
$c->where(array(
'published' => true,
'deleted' => false,
));
/* взять все наследники ресурса с ID 390 */
$children = $modx->getChildIds(390);
if (count($children) > 0) {
$c->where(array(
'id:IN' => $children,
));
}
/* отсортировать новые сверху */
$c->sortby('menuindex','ASC');
/* взять ресурсы как xPDOObjects */
$resources = $modx->getCollection('modResource',$c);
$output = '';
foreach ($resources as $resource) {
$output .= ''.$resource->get('pagetitle').' ';
}
return $output;
Это делает то, что нам нужно, но содержит внутри HTML код. Нас такое не устраивает. Это не даёт пользователю возможность контролировать разметку или менять её, если он это захочет сделать. Нам нужно больше гибкости.
Шаблонизация сниппета
Во-первых, давайте создадим чанк, который мы будем использовать для каждого элемента в результирующем выводе. Назовём его "ResourceItem" и код содержимого назначим как:
В основном, мы пользуемся тегами LI и помещаем несколько заполнителей туда, где находился наш контент. Мы имеет доступ к каждому полю в ресурсе и теперь мы просто используем ID и поле ресурса pagetitle. Выражение [[~ говорит MODx, чтобы сделал ссылку от ID переданного через [[+id]] параметр. Давайте добавим параметр по-умолчанию к сниппету, называемый 'tpl' к верху нашего сниппет кода:
$tpl = $modx->getOption('tpl',$scriptProperties,'ResourceItem');
Этим мы получим в распоряжение параметр &tpl= от вызова Сниппета поскольку $scriptProperties просто содержит все параметры в вызове Сниппета. Если 'tpl' не существует, то по-умолчанию getOption является значением ResourceItem (чанк, который мы создали недавно).
После этого мы меняем цикл по каждому элементу в Сниппете на такой:
foreach ($resources as $resource) {
$resourceArray = $resource->toArray();
$output .= $modx->getChunk($tpl,$resourceArray);
}
Код вначале возвращает объект modResource в массив пар field=name (например, $resourceArray ['pagetitle'] - это pagetitle) используя метод toArray(). Далее мы используем $modx->getChunk() для передачи нашего tpl чанка и массива ресурсов в него как параметры. MODx парсит чанк, заменяет параметры и возвращает нам некоторый контент.
Теперь пользователь может вызывать сниппет этим способом для перезаписи чанка для каждого ресурса с помощью такого вызова:
Это значит, что пользователи могут шаблонизировать их результаты вызова как им угодно – используя теги Lis или поля таблиц, в общем что угодно! Вы создали гибкий и мощный сниппет!
Добавление класса для Ряда
Если мы хотим, чтобы пользователи могли определять CSS класс для каждого LI ряда, но не могли делать свои собственные чанки. Тогда мы просто добавляем параметр по-умолчанию 'rowCls' для кода нашего сниппета вверху прямо под нашим первым вызовом getOption:
$rowCls = $modx->getOption('rowCls',$scriptProperties,'resource-item');
Это говорит MODx, что по-умолчанию &rowCls класс ряда для сниппета - это 'resource-item'. Давайте отредактируем наш чанк ResourceItem:
И далее изменим наш цикл для каждого элемента:
foreach ($resources as $resource) {
$resourceArray = $resource->toArray();
$resourceArray['rowCls'] = $rowCls;
$output .= $modx->getChunk($tpl,$resourceArray);
}
Обратите внимание как мы в прямой форме определили переменную 'rowCls' в наш массив параметров $resourceArray. Мы так сделали, потому что у нас уже есть значение rowCls ранее в этом сниппете (с вызовом getOption) и теперь мы знаем, что он не будет отличаться для каждого ряда.
Передача пользовательского ID
Если мы хотим, чтобы пользователь имел возможность передавать от какого предка брать ресурсы. Тогда мы просто добавляем параметр 'id' к коду нашего сниппета вверху под вызовом getOption:
$id = (int)$modx->getOption('id',$scriptProperties,390);
В основном позволять пользователям переписывать (назначать) родительский ID для Сниппета – для примера скажем Ресурс 123 с параметром &id=`123` - в их вызове сниппета. Мы хотим, чтобы по умолчанию он равнялся 390. И далее мы поменяем строку getChildIds для этого:
$children = $modx->getChildIds($id);
Очевидно, что вы могли бы добавить больше функций к этому сниппету, таким как firstRowCls (для первого ряда результата вызова), lastRowCls, firstRowTpl, sortBy, sortDir, limit и всё угодно, что вы смогли бы придумать. Мы могли бы даже сделать фильтр 'published' как параметр или скрывать ресурсы, которые являются папками для других ресурсов и др. Теперь важно, что вы имеете общее представление о создании пользовательского сниппета.
Для справки, наш конечный код выглядит вот так:
$tpl = $modx->getOption('tpl',$scriptProperties,'ResourceItem');
$id = (int)$modx->getOption('id',$scriptProperties,390);
$rowCls = $modx->getOption('rowCls',$scriptProperties,'resource-item');
$c = $modx->newQuery('modResource');
$c->where(array(
'published' => true,
'deleted' => false,
));
$children = $modx->getChildIds($id);
if (count($children) > 0) {
$c->where(array(
'id:IN' => $children,
));
}
$c->sortby('menuindex','ASC');
$resources = $modx->getCollection('modResource',$c);
$output = '';
foreach ($resources as $resource) {
$resourceArray = $resource->toArray();
$resourceArray['cls'] = $rowCls;
$output .= $modx->getChunk($tpl,$resourceArray);
}
return $output;
Оригинал статьи
15-11-2011
сниппеты приёмы MODx Revolution
Виктор Матушевский
sirega
23.11.2011 17:01здравствуйте, не ответите мне на такой вопрос, на сколько хорошо нужно знать php чтобы делать на modx все что душе угодно.
Viktorminator
23.11.2011 19:14Я тоже недавно задал приблизительно такой же вопрос "Сколько времени нужно провести с MODx, чтобы общаться с ним на ты". Я думаю, нужно знать MODx как фреймворк, если умеете использовать его методы и классы, тогда сможете сделать всё, что угодно. Функционал делаете на php и помещаете в сниппеты, отображение в чанки и css, Объекты такие как продукты (объявления, новости и т.д.) делаете как ресурсы. Для понимания MODx как фреймворка нужно разобраться с xPDO (уже начал работу над уроками). Ничего суперсложного в пхп и MODx с пхп нет, нужно просто сесть и разобраться. По аналогии могу ответить вопросом на вопрос - насколько хорошо нужно знать html и css, чтобы делать на MODx суперкрасивые сайты.
Sirega
23.11.2011 19:56Html и Css знаю неплохо, чтобы делать красивые сайты достаточно знать процентов 10 из всех html и css тегов, Дримвиавер в верстке неплохо помогает.
OhMyGodMan
29.06.2012 15:55Нда, "чтобы делать красивые сайты достаточно знать процентов 10 из всех html и css тегов" и "Дримвиавер в верстке неплохо помогает."
Настоящий web-master! Может сразу на Юкоз? )
Игорь
10.03.2013 13:25отчасти он прав. чтобы сделать сайт, далеко не обязательно использовать 100% тегов html и css правил. прежде всего важен результат и кроссбраузерность. а то, как это сделано пользователям сайта будет абсолютно по барабану.
Глеб
12.09.2013 15:5910% нет - ребят этого вообще недостаточно!
Rasul Abu Muhammad Amin
27.10.2014 22:40Спасибо за статью. Не могли бы вы подсказать один момент.
Как по-проще можно сделать вложенный чанк и вызов в сниппете. Например, обернуть ResourceItem в какой нибудь чанк ResourceWrapper с