Skip to content

Введение ​

При установке PageBlocks регистрирует семь сниппетов MODX. Они нужны, чтобы до компонента можно было дотянуться из обычного шаблона MODX: вставил вызов — получил вывод. Без контроллера, без маршрута и без перехода на наш шаблонизатор.

СниппетЧто делает
pbListУниверсальный листер с пагинацией по любой модели
pbBlocksВыводит блоки конструктора, прикреплённые к ресурсу
pbResourcesПлоский список ресурсов MODX
pbUsersПлоский список пользователей
pbMenuДерево ресурсов для навигации
pbFiltersГотовая форма фильтров для таблицы конструктора
pbJsonВыводит JSON через инлайн-шаблон

Как вызывать ​

Работают оба написания. В шаблоне MODX:

[[!pbList? &model=`PbResource` &parent=`[[*id]]` &tpl=`myItem` &limit=`10`]]

В шаблоне Fenom:

php
{'!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:

php
<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, pbResourcespageblocks.resource
pbUserspageblocks.user
pbMenupageblocks.menu + pageblocks.menu.wrapper
pbBlockspageblocks.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`]]
html
<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 requiredpbFilters без таблицы
table 'X' has no fields marked filterableтаблица есть, галочек «фильтруемое» нет
nothing found, the query returned no rowsс чанком всё хорошо — под where/scopes ничего не попало

Блок показывается только вошедшему в менеджер, поэтому &showLog можно оставить в шаблоне на время вёрстки: посетитель увидит один вывод. Всё, кроме «nothing found», уходит ещё и в лог ошибок MODX — с файлом и строкой, откуда пришло.

© PageBlocks 2019-present