pdoParser
pdoParser является заменой класса modParser.
Обработка плейсхолдеров
Его задача - стараться быстро разобрать теги MODX без создания объектов, как это делает оригинальный парсер. pdoParser умеет работать только с простыми тегами, без фильтров и условий, то есть:
[[%tag]]
- строка лексикона[[~id]]
- ссылка[[+tag]]
- обычные плейсхолдеры[[++tag]]
- системные плейсхолдеры[[*tag]]
- плейсхолдеры ресурса[[#tag]]
- плейсхолдеры FastField
Специальные теги FastField были предложены Виталием Киреевым в одноимённом дополнении. После согласованию с автором, pdoParser был обучен работе с ними.
Он умеет:
- Выводить поля ресурсов:
[[#15.pagetitle]]
,[[#20.content]]
- Выводить ТВ параметры ресурсов:
[[#15.date]]
,[[#20.some_tv]]
- Выводить поля товаров miniShop2:
[[#21.price]]
,[[#22.article]]
- Выводить массивы ресурсов и товаров:
[[#12.properties.somefield]]
,[[#15.size.1]]
- Выводить глобальные массивы:
[[#POST.key]]
,[[#SESSION.another_key]]
- Распечатывать массивы для отладки:
[[#15.colors]]
,[[#GET]]
,[[#12.properties]]
Цифра после решетки - это id ресурса, от которого нужно выбрать данные.
Все эти теги pdoTools обрабатывает без создания объектов modElement, поэтому работает немного быстрее чем родные методы MODX. Если же плейсхолдер вызван с какими-то параметрами, то он уйдёт в родной modParser.
Шаблонизатор Fenom
С версии 2.0 в состав pdoTools входит шаблонизатор Fenom анонс от автора на Хабре.
Работает только при включенном pdoParser и если разрешен в системных параметрах.
Возможности
- Компилируется в нативный PHP код, который выполняется гораздо быстрее, чем теги MODX. Прирост, в среднем 30% - 50%.
- Может работать и в чанках и на страницах сайта
- Теги Fenom и MODX никак не мешают друг другу и работают одновременно
- Если в чанке нет плейсхолдеров MODX, то парсер MODX не запускается
- Если в чанке нет тегов Fenom, то он тоже не запускается
- Поддерживаются даже @INLINE чанки
- В отличии от других решений, вам не нужно никаким образом менять или переписывать свои сниппеты - всё работает через методы
pdoTools::getChunk()
иpdoTools::parseChunk()
автоматически. - Все ошибки компиляции пишутся в системный журнал
Настройки
- pdotools_fenom_default включает обработку синтаксиса Fenom во всех чанках сайта.
- pdotools_fenom_parser включает обработку синтаксиса Fenom на страницах сайта. Контент ресурсов, шаблоны - везде. По умолчанию отключено.
- pdotools_fenom_php включает возможность выполнения произвольных функций PHP в шаблонах через
{$.php.функция()}
. Опция эта очень опасная, так что тоже отключена. - pdotools_fenom_modx - чуть менее опасная опция, но во многих случаях, пока, необходимая - работа с объектами modX и pdoTools через переменные
{$modx}
и{$pdoTools}
. Если вы не доверяете своим менеджерам - выключите её от греха подальше, потому что через объект modX можно удалить начисто весь сайт. - pdotools_fenom_cache - включает кэширование чанков (только чанков, не страниц сайта) через кэшер MODX (а не как раньше). Стоит использовать только на продакшн сайтах при больших и сложных чанках.
Порядок запуска шаблонизатора
Если включен pdoParser и системная опция pdotools_fenom_parser, то шаблонизатор запускается ровно вот здесь.
В этот момент все кэшированные чанки и сниппеты на странице обработаны (или загружены из кэша) и вы можете использовать вот такие конструкции:
{if $.get.test == 1}
[[!pdoResources?parents=`0`]]
{else}
[[!pdoMenu?parents=`0`]]
{/if}
То есть, в зависимости от $_GET['test']
на странице будет запущен или один сниппет или другой. Парсер MODX же запустил бы оба и результат выполнения одного неподходящего просто не показал.
Таким образом, вы можете реализовывать гораздо более сложную логику работы сайта даже с отключенными опциями pdotools_fenom_php
и pdotools_fenom_modx
. Понятное дело, что вызов тегов Fenom на страницах сайта никак не кэшируется.
Внутри чанков Fenom всегда выполняется в первую очередь, позволяя также разделять их содержимое для MODX, в зависимости от условий.
Кэширование чанков Fenom
По умолчанию этот функционал Fenom отключен, потому что по моим тестам, толку от него в MODX нет. Но, это на моих мелких и простых чанках, а у вас может быть что-то посложнее.
Поэтому вы можете включить системную настройку pdotools_fenom_cache и тогда скомпилированные шаблоны будут сохранены в /cache/default/fenom/
в зависимости от своего типа.
Чанки из БД кэшируются под своими id, а INLINE именуются как хэш от своего содержимого, то есть - путь к обычному чанку будет выглядеть как cache/default/fenom/**chunk/90.cache.php
, а к INLINE уже как cache/default/fenom/inline/35e115c27fdc3814b6f41a1015aa67e6.cache.php
.
Отсюда следует, что нормальные чанки из БД кэшируются намертво, и обновляются только при очистке системного кэша, а INLINE чанки при изменении контента сохраняются под новым именем и весь кэш чистить не нужно.
Как это работает дальше?
При первом запуске с пустым кэшем pdoTools получает нужный чанк, определяет его тип и отдаёт в Fenom. Тот компилирует шаблон и сохраняет его во внутренний кэш pdoTools методом setStore()
. Этот кэш находится в ОЗУ и сохраняется только на время выполнения скрипта, он нужен чтобы не компилировать 10 раз один и тот же чанк при выводе pdoResources.
А вот если включена опция pdotools_fenom_cache
, то исходный код скомпилированного шаблона сохраняется на HDD сервера, и при следующем запуске Fenom уже не нужно его компилировать. Кэшер MODX отдаёт исходный код, из него получается объект Fenom\Render
который передаётся в setStore()
и оттуда уже работает.
Собственно, вопрос в том, что для вас будет быстрее - поднять скомпилированный шаблон из кэша, или скомпилировать его заново.
Обычно выходит, что на маленьких и простых чанках (как у сниппетов pdoTools) выигрыша нет, а лишних файлов много, а вот на больших и сложных чанках (которые вы наверняка создадите, используя возможности Fenom) разница уже может быть. Время компиляции и работы с кэшем выводится в &showLog=`1`
, так что каждый может проверить сам.
Примеры
Стандартный чанк tpl.Tickets.comments.wrapper
из компонента Tickets
<div class="comments">
[[+modx.user.id:isloggedin:is=`1`:then=`
<span class="comments-subscribe pull-right">
<label for="comments-subscribe" class="checkbox">
<input type="checkbox" name="" id="comments-subscribe" value="1" [[+subscribed:notempty=`checked`]] />
[[%ticket_comment_notify]]
</label>
</span>
`:else=``]]
<h4 class="title">[[%comments]] (<span id="comment-total">[[+total]]</span>)</h4>
<div id="comments-wrapper">
<ol class="comment-list" id="comments">[[+comments]]</ol>
</div>
<div id="comments-tpanel">
<div id="tpanel-refresh"></div>
<div id="tpanel-new"></div>
</div>
</div>
Он же, переписанный для работы с Fenom
<div class="comments">
{if $modx->user->isAuthenticated($modx->context->key)}
<span class="comments-subscribe pull-right">
<label for="comments-subscribe" class="checkbox">
<input type="checkbox" name="" id="comments-subscribe" value="1" {$subscribed != '' ? 'checked' : ''} />
{$modx->lexicon('ticket_comment_notify')}
</label>
</span>
{/if}
<h4 class="title">{$modx->lexicon('comments')} (<span id="comment-total">{$total}</span>)</h4>
<div id="comments-wrapper">
<ol class="comment-list" id="comments">{$comments}</ol>
</div>
<div id="comments-tpanel">
<div id="tpanel-refresh"></div>
<div id="tpanel-new"></div>
</div>
</div>