Сравнение шаблонизаторов
Хочу поделится своим мнением о различных шаблонизаторах, которые на данный момент используются в MODX. Думаю, это будет интересно не только новичкам, но и опытным модыксерам, которые не задумываются об этой стороне дела. Итак, на сегодняшний день активно используются всего два шаблонизатора — встроенный и Fenom. Были попытки расширить этот список ещё парочкой — Smarty и Twig. Но если заглянуть в официальный репозиторий, то будет видно, что они давно уже не поддерживаются. Поэтому о них говорить не будем. Не так давно я также решил внести свою лепту и предложил сообществу компонент ZoomX, в котором из коробки идёт шаблонизатор Smarty. Только принцип его работы отличается от других, озвученных выше. Но об этом я расскажу дальше.
Шаблонизатор MODX
Этот шаблонизатор работает из коробки. Авторы MODX придумали интересную реализацию, не похожую на других. Контент многократно парсится с помощью регулярных выражений. Такой способ парсинга к сожалению накладывает большие ограничения на функциональные возможности. Поэтому логика в шаблонах минимальная и ограничивается в основном только фильтрами. Подразумевается, что сложная логика должна быть вынесена в сниппеты. Сниппет IF является ярким примером попытки добавить управляющую конструкцию в шаблонизатор. Выглядит, конечно, не очень.
Ещё ряд неудобств добавляют невозможность расширять шаблоны. А с развитием систем поддержки версионности и систем разработки (IDE) хранение основных элементов шаблонизатора в базе данных является сильным ограничительным фактором при выборе MODX в качестве CMS.
Но несмотря на эти недостатки этот шаблонизатор будет хорошим выбором при создании сайтов, в которых не планируется сложной логики в шаблонах, не стоит задача по поддержке версионности и постоянному деплою, а разработку можно вести в админке. Для портфолио, блогов и т.п. сайтов этот шаблонизатор подходит на все 100%.
Кстати!
Благодаря многократному парсингу контента шаблонизатор MODX позволяет не соблюдать строгую последовательность исполнения. Например, вы можете вставить тег плейсхолдера перед сниппетом, который его добавляет.
[[+someVar]] ... [[!Snippet]] // Определяет плейсхолдер someVar
На первой и второй итерациях парсер MODX пропустит тег [[+someVar]]
, а на третьей распарсит добавленным в сниппете значением.
Шаблонизатор Fenom
Если вам всё-таки нужна бОльшая свобода в реализации логики в шаблонах, то придётся использовать шаблонизатор помощнее. Компонент pdoTools с версии 2.0.0 предлагает Fenom. С его помощью вы можете реальзовать любую логику в шаблонах. Это полноценный PHP шаблонизатор. Он компилирует данный ему контент в php файл. Таким образом в нём можно использовать все конструкции языка PHP.
Но и тут есть свои недостатки. К сожалению, он не является самостоятельным шаблонизатором. Он добавляется в MODX в качестве дополнительного парсера контента. Таким образом в шаблонах доступны 2 синтаксиса и не все знают, в какой последовательности обрабатывается контент.
В сети можно найти вот такие примеры использования Fenom:
[[!pdoResources? &parents=`0` &tpl=`@INLINE <p>{$id} - {$pagetitle} {$createdon | dateago}</p>` ]]
На первый взгляд всё нормально. Но такой вызов вернёт неожиданный результат. Причина — первым контент парсит Fenom. Соответственно он обработает свои теги ({$id}
, {$pagetitle}
и {$createdon | dateago}
) и вернёт вместо них пустые строки, так как этих плейсхолдеров ещё нет (планируется, что они появятся позже в INLINE чанке). Далее полученный контент обрабатывает парсер MODX. Только чанк уже распарсен и появившиеся плейсхолдеры вставлять некуда. Таким образом, вам не удастся пробросить в сниппет такую строку.
Такой вариант сработал бы, если бы вместо INLINE чанка был обычный или вызывался бы кэшируемый сниппет — на этой итерации (парсинг кэшируемых тегов) Fenom не запускается.
Или вот недавно меня спросили, почему не выводится статистика
[[!siteStatistics? &toPlaceholders=`1`]] <div>{$_modx->getPlaceholder('stat.views') | declension : 'просмотр|просмотра|просмотров' : true}</div>
Ответ тот же — очерёдность парсинга. И так на каждой итерации. И вы никак не сможете исключить подобные ошибки.
Очевидным решением будет использование только тегов Fenom. Но есть ещё ряд моментов с кэшированием и файловыми элементами. Некоторые уже наступили на эти грабли. Я подробно рассказывал про шаблонизаторы MODX и Fenom в этом видео.
Кстати, что интересно, Fenom добавлен в pdoTools много лет назад, но ни один сниппет из этой библиотеки не поддерживает полноценную работу с ним. Поэтому приходится конвертить в JSON и обратно или делать такой финт.
Если покопать дальше, то найдётся ещё пара вопросов типа компиляции всех чанков на каждый запрос и компиляции страницы на каждой итерации MODX парсера. Но это технические вопросы касающиеся оптимизации. Верстальщикам как правило до этого нет дела. Да и при расширении шаблонов придётся делать лишний запрос к БД.
В общем, Fenom добавил в MODX больше возможностей для разработки и интеграции вёрстки, а pdoTools улучшил ряд моментов в MODX для более оптимальной работы Fenom.
Шаблонизатор Smarty
С выходом моего компонента ZoomX в MODX можно верстать используя шаблонизатор Smarty. Но я не стал повторять реализацию Fenom. Мы много лет говорим о том, что MODX отстаёт от современных подходов разработки. Поэтому в моей реализации Smarty полностью заменяет шаблонизатор MODX и работает именно так, как он был задуман — однократная компиляция контента. И благодаря Opcache скомпилированный шаблон запускается мгновенно. Я показывал результат обработки 100 ресурсов с одним чанком аналогично этому тесту Fenom. Прирост скорости до 50%. Тест, конечно, искусственный, но даёт сравнительное представление по отношению к тесту Fenom.
Ещё важное отличие от реализации Fenom — Smarty заточен под файлы. Т.е. инструкция {include 'index.tpl'}
загрузит файл, а не чанк из базы данных в случае Fenom. В современной разработке никто не работает с кодом из базы данных. В ней держат только информацию.
В процессе знакомства со Smarty я могу отметить некоторые преимущества перед Fenom. Например, в Smarty можно легко перенести концепцию кэширования элементов и тегов. В MODX это делается добавлением восклицательного знака вначале тега. В Smarty в тег добавляется атрибут nocache
или код заключается в аналогичный блок. Таким образом вы получаете скомпилированный шаблон с динамическим куском кода. Fenom так не умеет. Поэтому он вынужден использовать концепцию MODX со знаком "!" — проверять наличие вначале имени этого знака. Но согласитесь, такая запись {$_modx->runSnippet('!Snippet')}
выглядит хуже [[!Snippet]]
. В последнем случае мы визуально имя отделяем от знака "!". Ну и проблема файловых сниппетов — они всегда кэшируются. А чанки, добавленные через include
наоборот, даже если восклицательного знака нет.
Ещё в Smarty очень удобный механизм добавления плагинов (функций, модификаторов и т.д.). Он проще и оптимизирован под работу по требованию. Ну и если сравнить по функциональности, то Smarty также имеет преимущества перед Fenom.
Заключение
Вот такой беглый анализ. Выбирайте шаблонизатор в зависимости от задачи. Лично мне близок подход разработки из мира фреймворков. Поэтому я, конечно, выбираю последний вариант. Такой же принцип используется и в October CMS, а также внедрили в Evolution CMS. В ближайшее время я планирую добавить в ZoomX библиотеку инструментов наподобие pdoTools. И после этого перевести сайт на Smarty. Постараюсь всё это заснять на видео.
Комментарии ()
Вы должны авторизоваться, чтобы оставлять комментарии.
Да и за развитие MODX в этом направлении, спасибо.
Библиотеку инструментов планируете создать, используя PDO?
Не, это слишком накладно писать свою ORM. Есть мысли прикрутить Eloquent. Тут ещё предстоит оценить фронт работ. А работы явно будет много. Но есть большое желание отказаться от xPDO. Для начала можно сделать слой абстрации, чтобы можно было переподключать ORM.
Я верю, что Fenom может быть быстрее других. Но в стандартной реализации, а не костыльной. В MODX он добавляется как простой парсер, чтобы использовать логику в разметке. В данном случае все его преимущества нивелируются.
Кроме того, согласно этой статье, Smarty выигрывает у других шаблонизаторов.Я тоже делал тест, аналогичный тесту в документации pdoTools. Smarty быстрее шаблонизатора MODX + Fenom.
Я выбрал Smarty только потому, что он уже есть в MODX и не нужно тащить лишнюю зависимость. В дальнейшем я планировал добавить все популярные шаблонизаторы отдельными пакетами. Можно было бы и Fenom добавить, но в качестве полноценного шаблонизатора, а не как в pdoTools.
а можно пример? это прям интересно! какой прирост в скорости?
fenom ещё ведь и всего в 9 файлах!
Ещё автор Fenom кокетливо умалчивает о том, что его шаблонизатор функционально не дотягивает до Smarty. Последний, например, может полностью заменить шаблонизатор MODX. А вот Fenom не может. В частности кэширование тегов. Поэтому автору pdoTools пришлось переносить логику с восклицательным знаком, который некорректно работает с файловыми элементами и с некоторыми конструкциями чанков.
Также как сейчас в ZoomX используется Smarty — берётся контент и парсится только один раз, шаблон компилируется и оптимизируется Opcache. Fenom парсит контент минимум 2 раза (согласно логике шаблонизатора MODX) без компиляции и оптимизации. Кроме того у Fenom отсутствует возможность прокинуть переменную из вне. Для этого нужно ставить отдельный плагин. В pdoTools для реализации этого механизма используется хранилище плейсхолдеров MODX (напомню, это массив строк). Таким образом, у вас в плейсхолдерах MODX висят объекты $_modx и $pdoTools. Нормально?
Вот тут уже отвечал. Только прирост достигается не из-за Smarty, а за счёт изменения концепции. Если вместо Smarty использовать Blade/Twig/Fenom, то будет тоже самое (с небольшой разницей из-за особенностей каждого шаблонизатора).
Постараюсь в ближайшее время перенести эти 2 теста сюда в раздел документации.