pdoParser
pdoParser — является заменой класса modParser. Его задача — стараться быстро разобрать теги MODX без создания объектов.
Оглавление
Задача pdoParser быстрый разбор тэгов MODx без создания объектов, как это делает оригинальный парсер.
Обработка плейсхолдеров
pdoParser умеет работать только с простыми тегами, без фильтров и условий, то есть:
[[%tag]]
— строка лексикона.[[~id]]
— ссылка.[[+tag]]
— обычные плейсхолдеры.[[++tag]]
— системные плейсхолдеры.[[*tag]]
— плейсхолдеры ресурса.[[#tag]]
— плейсхолдеры FastField.
Специальные теги FastField были предложены Виталием Киреевым в одноимённом дополнении. После согласованию с автором, pdoParser был обучен работе с ними.
Он умеет:
Выводить поля ресурсов: [[#15.pagetitle]]
, [[#20.content]]
.
Выводить TV параметры ресурсов: [[#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 никак не мешают друг другу и работают одновременно.
- Если в чанке нет тегов 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 отключен, потому что по тестам автор pdoTools, толку от него в 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>
Время запросов: 0,1163 s
Количество запросов: 24
Источник: cache