• Блог
  • Сравнение шаблонизаторов

Хочу поделится своим мнением о различных шаблонизаторах, которые на данный момент используются в 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. Постараюсь всё это заснять на видео.

0   3014

Комментарии ()

  1. shock 20 января 2021 # +1
    Спасибо, за обзор, Сергей!
    Да и за развитие MODX в этом направлении, спасибо.
    Библиотеку инструментов планируете создать, используя PDO?
    1. Сергей Шлоков 20 января 2021 # 0
      Мы одной крови!;)

      Библиотеку инструментов планируете создать, используя PDO?
      Не, это слишком накладно писать свою ORM. Есть мысли прикрутить Eloquent. Тут ещё предстоит оценить фронт работ. А работы явно будет много. Но есть большое желание отказаться от xPDO. Для начала можно сделать слой абстрации, чтобы можно было переподключать ORM.
    2. Alex 19 марта 2021 # 0
      странно, но судя по бенчмаркам, fenom уделывает смарти только так, может быть это лишь синтетические тесты?
      1. Сергей Шлоков 20 марта 2021 # 0
        Это тест 2014 года. Актуальность его на сегодняшний день сомнительна.

        Я верю, что Fenom может быть быстрее других. Но в стандартной реализации, а не костыльной. В MODX он добавляется как простой парсер, чтобы использовать логику в разметке. В данном случае все его преимущества нивелируются.

        Кроме того, согласно этой статье, Smarty выигрывает у других шаблонизаторов.Я тоже делал тест, аналогичный тесту в документации pdoTools. Smarty быстрее шаблонизатора MODX + Fenom.

        Я выбрал Smarty только потому, что он уже есть в MODX и не нужно тащить лишнюю зависимость. В дальнейшем я планировал добавить все популярные шаблонизаторы отдельными пакетами. Можно было бы и Fenom добавить, но в качестве полноценного шаблонизатора, а не как в pdoTools.
        1. Alex 20 марта 2021 # 0
          Можно было бы и Fenom добавить, но в качестве полноценного шаблонизатора, а не как в pdoTools.
          вот тут интересно, как это сделать? можно хотя бы в двух словах?
          Я тоже делал тест, аналогичный тесту в документации. Smarty быстрее.
          а можно пример? это прям интересно! какой прирост в скорости?
          fenom ещё ведь и всего в 9 файлах!
          1. Сергей Шлоков 21 марта 2021 # 0
            Если честно, я не понимаю, что это за фетиш такой с количеством? А если ещё и самому посчитать, то у Smarty получится около 200 файлов. И как видим, основная часть — плагины, которые подключаются по требованию. 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 теста сюда в раздел документации.
      2. Modman 12 сентября 2022 # 0
        Добрый день! А компонент с modx 3.0.1 совместим?
        1. Сергей Шлоков 12 сентября 2022 # 0
          К сожалению пока нет.
          1. Modman 12 сентября 2022 # 0
            Сергей, а на 2.8.4 работает?
            1. Сергей Шлоков 12 сентября 2022 # 0
              Работает.

        Вы должны авторизоваться, чтобы оставлять комментарии.

        Выделите опечатку и нажмите Ctrl + Enter, чтобы отправить сообщение об ошибке.