Введение
При установке PageBlocks регистрирует семь сниппетов MODX. Они нужны, чтобы до компонента можно было дотянуться из обычного шаблона MODX: вставил вызов — получил вывод. Без контроллера, без маршрута и без перехода на наш шаблонизатор.
| Сниппет | Что делает |
|---|---|
pbList | Универсальный листер с пагинацией по любой модели |
pbBlocks | Выводит блоки конструктора, прикреплённые к ресурсу |
pbResources | Плоский список ресурсов MODX |
pbUsers | Плоский список пользователей |
pbMenu | Дерево ресурсов для навигации |
pbFilters | Готовая форма фильтров для таблицы конструктора |
pbJson | Выводит JSON через инлайн-шаблон |
Как вызывать
Работают оба написания. В шаблоне MODX:
[[!pbList? &model=`PbResource` &parent=`[[*id]]` &tpl=`myItem` &limit=`10`]]В шаблоне Fenom:
{'!pbList' | snippet: ['model' => 'PbResource', 'tpl' => 'myItem', 'limit' => 10]}Восклицательный знак оставляйте: эти сниппеты рассчитаны на некэшированный вызов, иначе MODX заморозит первый результат в кэше страницы.
Массивы в параметрах — это JSON
Сниппет MODX получает все параметры строками, поэтому всё, что по смыслу массив, пишется JSON-ом и разбирается самим сниппетом:
[[!pbList?
&model=`PbResource`
&tpl=`myItem`
&where=`{"template":4}`
&orderBy=`{"publishedon":"desc"}`
]]Если JSON невалидный, значение уходит как есть — поэтому обычный список id вида 12,7,3 остаётся списком id.
Общие параметры вывода
У pbResources, pbUsers, pbMenu и pbBlocks один контракт вывода — тот же, что знаком по pdoTools:
| Параметр | По умолчанию | Описание |
|---|---|---|
tpl | дефолтный чанк компонента | Чанк одной строки. Без него сниппет берёт свой дефолтный чанк, поэтому голый [[!pbResources]] уже что-то выводит. |
tplWrapper | Чанк-обёртка всего вывода. Получает output и total. | |
tplEmpty | Чанк, который выводится вместо результата, когда ничего не нашлось. | |
outputSeparator | \n | Чем склеивать строки. |
toPlaceholder | Вывод уходит в плейсхолдер MODX, сниппет возвращает пустоту — вызов можно поставить наверху шаблона, а напечатать ниже. | |
showLog | Печатает рядом с выводом то, на что сниппет пожаловался. Видно только вошедшему в менеджер. |
Внутри tpl строка доступна как item, а её номер (с единицы) — как idx:
<div class="card">
<span class="num">{$idx}</span>
<a href="{$item->uri}">{$item->pagetitle}</a>
</div>Какой чанк имеется в виду в tpl
Одно правило на все сниппеты, и то же самое, по которому живёт остальной PageBlocks — источник указывается внутри значения, а не отдельным параметром:
&tpl=`myItem` → чанк MODX с именем myItem
&tpl=`file:chunks/myItem` → core/App/elements/chunks/myItem.tpl
&tpl=`file:pbShop:chunks/card` → файл из именованного источника
&tpl=`@INLINE <b>{$item->pagetitle}</b>` → шаблон строкойРасширение .tpl дописывается, если его не указали. Отката между источниками нет: несуществующий file: — это ошибка в логе, а не тихий поиск в базе, поэтому опечатка никогда не разрешится молча во что-то другое.
chunk: устарел
chunk: означал «базу» в pbList, где голое имя было файлом, — противоположно pbResources, pbUsers и pbMenu, у которых голое имя всегда было базой, а chunk: не выводил вообще ничего. Теперь голое имя — база везде. chunk: работает ещё одну мажорную версию и пишет в лог MODX, что устарел.
Нулевой шаг
У каждого сниппета-списка есть дефолтный чанк, и пакет ставит его обычной записью — её видно в дереве элементов, можно править на месте или скопировать рядом:
| Сниппет | Дефолтный чанк |
|---|---|
pbList, pbResources | pageblocks.resource |
pbUsers | pageblocks.user |
pbMenu | pageblocks.menu + pageblocks.menu.wrapper |
pbBlocks | pageblocks.blocks.wrapper — обёртка .pb-page, на которой объявлены токены оформления; строк своим чанком он не рисует, каждый блок выводится тем чанком, который ему задали в конструкторе |
То есть [[!pbResources]] выводит список до того, как вы написали хоть один чанк. Передали &tpl — ваш побеждает.
Что обновление сделает с дефолтом, который вы правили
Установщик запоминает sha1 поставочного содержимого каждого дефолтного чанка — по нему обновление отличает вашу работу от нашей:
| Состояние записи | Что делает обновление |
|---|---|
| не трогали (хэш совпадает с поставочным) | перезаписываем, иначе исправления дефолта до вас не доедут |
| вы её правили | не трогаем, а в лог MODX уходит строка с именем чанка и путём к поставочному оригиналу |
| помечена статичной | не трогаем никогда, независимо от хэша: содержимое статичного элемента — это файл, и он ваш |
Обновляетесь с версии, которая хэшей ещё не писала? Тогда правку не отличить от смены дефолта, и выбирается безопасная сторона: остаётся ваша версия.
static ведёт в core/App, а не в каталог компонента
Поставьте галочку «статичный» — и содержимое дефолтного чанка переедет в core/App/elements/chunks/<имя>.tpl, в site-owned дерево, которое обновление только дополняет. Путь внутрь core/components/pageblocks/ означал бы, что файловый резолвер затирает ваше содержимое на каждом обновлении, формально «не трогая запись».
Нужны не HTML, а сами строки? Для этого есть хелперы — resources(), users(), — и из Fenom это вход по умолчанию.
Где лежит код сниппета
Семь сниппетов ставятся статичными элементами: исполняется файл из core/components/pageblocks/elements/snippets/, а запись в базе только регистрирует элемент. Обновление заменяет файл, запись не трогает.
Правка сниппета в менеджере пишет внутрь компонента
Элемент статичный, поэтому сохранение в менеджере запишет вашу правку в файл самого компонента — а следующее обновление этот файл перезапишет. Сниппет — код компонента: его не правят, его обновляют. Нужно другое поведение — скопируйте файл рядом под своим именем и зарегистрируйте свой сниппет; под ваши правки предназначены чанки.
Правка файла доезжает после сброса кэша: MODX компилирует элементы в core/cache/includes, и пока кэш не обновлён, исполняется скомпилированная копия. Так что после деплоя, который затронул эти файлы, сбросьте кэш MODX — из менеджера или вызовом $modx->getCacheManager()->refresh() из своего скрипта деплоя.
Почему пусто? &showLog
Сниппет, который ничего не вывел, — самое трудное в отладке MODX: тег исчезает со страницы, а причина остаётся в логе MODX, куда во время вёрстки никто не смотрит. Поэтому добавьте &showLog=`1` , и сниппет напечатает, на что пожаловался:
[[!pbList? &tpl=`crad` &showLog=`1`]]<pre class="pb-log">[Fenom] chunk 'crad' not found in the database; for a file write file:crad</pre>Что он ещё скажет вместо того, чтобы просто ничего не вывести:
| Сообщение | Что случилось |
|---|---|
chunk 'x' not found in the database; for a file write file:x | опечатка в tpl или чанк лежит файлом |
file chunks/x.tpl not found under … | file: указывает на несуществующий путь |
unknown model 'X' | &model не находится в PageBlocks\App\Models\ |
&table is required | pbFilters без таблицы |
table 'X' has no fields marked filterable | таблица есть, галочек «фильтруемое» нет |
nothing found, the query returned no rows | с чанком всё хорошо — под where/scopes ничего не попало |
Блок показывается только вошедшему в менеджер, поэтому &showLog можно оставить в шаблоне на время вёрстки: посетитель увидит один вывод. Всё, кроме «nothing found», уходит ещё и в лог ошибок MODX — с файлом и строкой, откуда пришло.