Шаблонизатор Smarty

Smarty - мощный и один из самых быстрых PHP шаблонизаторов. Так как он входит в ядро MODX, то выбор пал на него. У него много предустановленных плагинов (встроенные функции, пользовательские функции, встроенные модификаторы). ZoomX также добавляет несколько своих плагинов.

Но кроме обычного синтаксиса с модификаторами, Smarty в ZoomX умеет работать и с синтаксисом в стиле MODX - {'*pagetitle'}, {'%lexicon'}, {'++setting'}, {'~5'}.

Информация!

В шаблонах доступен объекты $modx и $zoomx, доступом к которым можно управлять системной настройкой zoomx_include_modx.

Модификаторы

chunk – вызвать чанк.

Параметр:

  • (array) properties - ассоциативный массив параметров.
// Кэшированный чанк
{'chunkName'|chunk:['foo' => 'bar']}
// Некэшированный чанк (Smarty syntax)
{'chunkName'|chunk:['foo' => 'bar'] nocache}
config – получить системную настройку.

Параметр:

  • (mixed) default - значение по-умолчанию в случае отсутствие указанной системной настройки.
//[[++site_name]]
{'site_name'|config}
css,
csstohead – зарегистрировать CSS в секции HEAD страницы.

Параметр:

  • (string) media - тип медиа.
{'assets/css/styles.css'|csstohead}
{'assets/css/styles.css'|csstohead:all}
dateAgo – выводит дату в формате "1 минуту назад", "5 часов назад", "2 дня назад". Если разница больше недели, то выводится просто дата в формате "d F Y, H:i". Формат можно переопределить в параметре.

Параметр:

  • (string) format - формат даты.
{'publishedod'|resource|dateAgo}  // 3 часа назад
{'17.10.2021 21:00'|dateAgo}  // 17 октября 2021, 21:00
{'17.10.2021 21:00'|dateAgo:'Y-m-d'}  // 2021-10-17
declension – склонение слов для числительных.

Параметр:

  • (array) words - массив из слов. Для русского языка 3 формы, для английского достаточно указать две.
  • (bool) include - выводить ли само число.
{4|declension:['день','дня','дней']}  // дня
{4|declension:['день','дня','дней']:true}  // 4 дня

{4|declension:['day','days']:true}  // 4 days
fuzzyDate – отображать дату в формате "вчера в 11:15", "сегодня в 06:00", "завтра в 15:30". В остальных случаях дата отображается в формате "d F Y, H:i". Формат можно переопределить в параметре.

Параметр:

  • (string) format - формат даты.
{'publishedod'|resource|fuzzyDate}  // Вчера в 17:15
html,
htmltobottom – зарегистрировать html блок в конце страницы.
{'HTML content'|htmltobottom}
htmltohead – зарегистрировать HTML блок в секции HEAD страницы.
{'HTML content'|htmltohead}
js,
jstobottom – зарегистрировать JS в конце страницы.

Параметр:

  • (bool) plaintext - указывает, является ли указанное значение ссылкой на файл (false) или яваскрипт текстом (true).
{'assets/js/scripts.js'|jstobottom}
{'<script>let foo = "bar";</script>'|jstobottom:true}
jstohead – зарегистрировать JS секции HEAD страницы.

Параметр:

  • (bool) plaintext - указывает, является ли указанное значение ссылкой на файл (false) или яваскрипт текстом (true).
{'assets/js/scripts.js'|jstohead}
{'<script>let foo = "bar";</script>'|jstohead:true}
ignore – не парсить указанный тег, а вывести как есть.
{'content'|resource|ignore}  // вывод: {'content'|resource}
// тоже самое используя стандартный синтаксис Smarty
{literal}
{'content'|resource}
{/literal}
ismember – проверка - является ли текущий пользователь членом указанных групп. Можно указать несколько групп или в строке через запятую или в массиве.
{if 'group1,group2'|ismember}
    Контент для пользователя, входящего в одну из указанных групп
{/if}

{if ['group1', 'group2']|ismember:true}
    Контент для пользователя, входящего во все указанные группы
{/if}
lexicon – вывести значение лексикона для указанного ключа.

Параметры:

  • (array) params - массив плейсхолдеров.
  • (string) language - код языка (если лексикон уже загружен) или строка параметрами в формате "язык:пространство_имён:топик", чтобы предварительно загрузить лексикон. Подробнее в официальной документации MODX.
# Вывести строку для уже загруженного лексикона.
//[[%lang]]
{'lang_key'|lexicon}
// with parameters
{'lang_key'|lexicon:['foo' => 'bar']}
# Загрузить лексикон перед обработкой
lang_key 
markdown – перевести контент из формата Markdown в HTML.

Параметр:

  • (bool) secure - режим безопасности. Используется для дополнительного кодирования пользовательского контента.
{'[[*pagetitle]] - [[++site_name]]'|modx}
modx – распарсить тег MODX. Может быть использован для парсинга тега ресурса или TV, в контенте которых есть теги. Используется парсер, указанный в настройке parser_class.
{'[[*pagetitle]] - [[++site_name]]'|modx}
parse – распарсить тег. Как и предыдущий модификатор может быть использован для парсинга тега ресурса или TV, в контенте которых есть теги. Но в отличие от предыдущего можно указывать какой парсер использовать.

Параметр:

  • (string) parser - класс парсера. По-умолчанию, используется указанный в системной настройке zoomx_parser_class.
// Использовать ZoomX парсер, указанный в настройке "zoomx_parser_class".
{'content'|resource|parse}
// Использовать парсер MODX.
{'[[*pagetitle]] - [[++site_name]]'|parse:'modParser'}
ph – получить MODX плейсхолдер.
//[[+modx.user.id]]
{'modx.user.id'|ph}
print – вывести отформатированное и экранированное значение.

Параметры:

  • (bool) pre - форматировать вывод. Оборачивает вывод в тег <pre>. По-умолчание, true.
  • (bool) esc - экранировать вывод. Использует функцию htmlspecialchars(). По-умолчание, true.
{$array|print}
// вывести необработанную строку
{$array|print:false:false}
resource – получить значение указанного поля текущего ресурса.

Параметр:

  • (string) defaultField - альтернативное поле ресурса, которое будет выведено, если начальное поле пустое.
{'pagetitle'|resource}
// значением по-умолчанию является другое поле ресурса.
{'longtitle'|resource:'pagetitle'}
// значение по-умолчанию является строкой.
{'longtitle'|resource|default:'Строка'}
// TV значение
{'tv'|resource}
snippet – запустить MODX сниппет.

Параметр:

  • (array) properties - массив параметров.
  • (int) cache_lifetime - время хранения результата в кэше в секундах.
// Кэшированный сниппет
{'snippetName'|snippet:['foo' => 'bar']}
// Некэшированный сниппет (Smarty syntax)
{'snippetName'|snippet:['foo' => 'bar'] nocache}
// Некэшированный сниппет в набором параметров
{'snippetName@PropSet'|snippet:['foo' => 'bar'] nocache}
// Кэширование на 10 минут. Обязательно вызывать с nocache.
{'snippetName'|snippet:['foo' => 'bar']:600 nocache}
tv – вывести TV текущего ресурса. Альтернатива модификатору resource для вывода TV.
{'tv_name'|tv}
url - генерировать URL для указанного ресурса. Подробности в официальной документации MODX.

Параметры:

  • (string|array) context - контекст. С версии 2.0 можно указать массив со всеми перечисленными параметрами.
  • (array) args - массив агрументов URL.
  • (integer|string) scheme - схема.
  • (array) options - массив опций.
{5|url}
{5|url:'web':['foo' => 'bar']:-1}
# С версии 2.0
{5|url:['scheme' => 'full']}
user – получить значение поля текущего пользователя.

Параметр:

  • (mixed) default - значение по-умолчанию, если указанное поле пользователя пустое (null).
{'username'|user}
{'fullname'|user:'username'}

Блоки

auth – выводит содержимое блока только для залогиненных пользователей. По-умолчанию проверка для текущего контекста. Но можно указать любой другой.
{auth nocache}
Контент для аутентифицированных пользователей.
{/auth}

Проверка для указанного контекста.

{auth context="mgr" nocache}
Контент для аутентифицированных в админке пользователей.
{/auth}
guest – выводит содержимое блока только для гостей.
{guest nocache}
Контент для неаутентифицированных пользователей.
{/guest}
modx – используется для парсинга содержимого блока с помощью MODX парсера, указанного в системной настройке parser_class.
{modx nocache}
<a href="[[~[[*id]]]]">[[*pagetitle]]</a>
{/modx}
parse – используется для парсинга содержимого блока. По-умолчанию используется парсер, указанный в системной настройке zoomx_parser_class. А там по-умолчанию указан "ZoomSmarty". Хотя можно указать и любой MODX парсер. Но для этого лучше использовать соответствующий блок modx.

Параметр:

  • (string) parser - класс парсера. Пользовательский класс должен быть предварительно загружен.
{parse nocache}
<a href="[[~[[*id]]]]">[[*pagetitle]]</a>
{/parse}

// Можно указать любой другой
{parse parser="pdoParser" nocache}
<a href="[[~[[*id]]]]">[[*pagetitle]]</a>
{/parse}

Важно!

Если включено кэширование шаблонов, то в блоках и модификаторах необходимо указывать атрибут nocache, отключающий кэширование результата,чтобы предотвратить кеширование динамических данных.

Кэширование

В Smarty заложены мощные возможности кэширования. Вы можете управлять кэшированием отдельных тегов также, как это делается в MODX с помощью знака !, но несколько иначе - используя специальный аттрибут nocache или одноимённый блок.

// Аттрибут
{'username'|user nocache}
// Блок
{nocache}
{'username'|user}
{'email'|user}
{/nocache}

Для подшаблонов (чанков по-нашему) возможностей больше. Для них можно указать даже время кэширования.

{include file="chunks/header.tpl" cache_lifetime=300}

Можно указать разные кэши одного подшаблона для разных условий

// Разные кэши для разных категорий
{include file="header.tpl" cache_id="cache_key_{$modx->resource->parent}" title="{$modx->resource->pagetitle}"}

Для сниппетов также можно указывать определённое время кэширования.

// Кэширование на 10 минут.
{'snippet'|snippet:['foo' => 'bar', 'tpl' => 'chunk.tpl']:600 nocache}
{run name='snippet' params=['foo' => 'bar', 'tpl' => '@INLINE {$pagetitle}'] cache_lifetime=600 nocache}

Управлять кэшированием можно с помощью системной настройки zoomx_caching. При разработке советую её отключать. Также кэш не будет создаваться для документов, у которых снят чекбокс "кэшируемый".

Информация!

Компилированные файлы шаблонов Smarty хранятся в папке, указанной в системной настройке zoomx_smarty_compile_dir. Очистить их можно или вручную или через механизм очистки кэша в админке. Файлы кэша хранятся в папке, указанной в системной настройке zoomx_smarty_cache_dir. Эта папка очищается при сохранении в админке любого элемента, ресурса, системной настройки и т.д. Данный подход является стандартным в MODX.

Файловые элементы

Понятие файловых элементов - исключительно модыксовское. В других системах подобных сущностей нет. Многие знакомы с ними по pdoTools. В ZoomX также добавлен подобный функционал.

Начнём с того, что для Smarty все шаблоны и подшаблоны (или чанки по модыксовски) являются файловыми. Поэтому достаточно в шаблоне страницы написать include.

{include "имя_файла_шаблона"}

Но что делать, если нужно использовать чанк в сниппете или передать в параметре? Для этого предусмотрен уже привычный по pdoTools механизм.

// Для передачи в параметрах сниппета на странице
{'mySnippet|snippet:['tpl' => '@FILE profile.tpl']'}
// API для использования в сниппете
$content = zoomx()->getChunk('@FILE profile.tpl', $user->toArray());

В шаблоне также можно использовать вариант с байндингом @FILE.

{'@FILE имя_файла_шаблона.tpl'|chunk}

Расширение .tpl можно не указывать — к имени файла будет автоматически добавлено расширение, указанное в системной настройке zoomx_template_extension.

Для файловых сниппетов также создана аналогичная чанкам инструкция - run.

// Кэшированный сниппет (если включено кэширование шаблонов Smarty).
{run file='file_snippet.php' params=['foo' => 'bar', 'tpl' => '@INLINE {$pagetitle}']}
// Кэширование данных на 10 минут. Сниппет должен вызываться некэшированным (с nocache).
{run file='file_snippet.php' params=['foo' => 'bar', 'tpl' => '@INLINE {$pagetitle}'] cache_lifetime=600 nocache}

Но доступен и синтаксис pdoTools.

// "pdoTools like" - через использование байндигна @FILE 
{'@FILE file_snippet'|snippet:['foo' => 'bar', 'tpl' => '@FILE file_chunk.tpl']}
// Использование объекта $zoomx (появляется при включении настройки "zoomx_include_modx") с сохранением в кэше на 10 минут.
{$zoomx->runFileSnippet('file_snippet', ['foo' => 'bar', 'tpl' => 'modx_chunk'], 600) }

Расширение .php можно не указывать — оно добавится автоматически.

Не забывайте, чтобы вызвать некэшированный сниппет, нужно указать атрибут nocache. В ZoomX не поддерживается логика MODX с восклицательным знаком перед именем тега.

Создание собственных плагинов

Для большей части задач можно использовать непосредственно функции PHP. Например, вместо {$string|trim} можно вызвать {trim($string)}. Если данных возможностей не хватает, то можно создать собственный модификатор или функцию. Сделать это можно двумя способами:

  1. Создать файл плагина следуя инструкции и положить его в папку smarty/custom_plugins/ в ядре компонента ZoomX. Он будет подключён автоматически. Если вы создали свою собственную папку плагинов, то не забудьте указать её в системной настройке smarty_custom_plugin_dir.
  2. Динамически подключить во время загрузки MODX с помощью метода registerPlugin(). Для этого необходимо создать плагин на событие OnHandleRequest и в нём подключить нужный функционал:
    <?php
    // OnHandleRequest
    
    function print_current_date($params, $smarty)
    {
      if(empty($params["format"])) {
        $format = "%b %e, %Y";
      } else {
        $format = $params["format"];
      }
      return strftime($format,time());
    }
    
    // Подключение функции
    parserx()->registerPlugin("function","date_now", "print_current_date");
    // Пробросить PHP функцию ucfirst в виде модификатора.
    $smarty->registerPlugin("modifier","ucfirst", "ucfirst");
    

    В шаблоне теперь доступна функция date_now и модификатор ucfirst.

    {date_now}
    {* Или с форматированием *}
    {date_now format="%Y/%m/%d"}
    
    {$name|ucfirst}
    
Выделите опечатку и нажмите Ctrl + Enter, чтобы отправить сообщение об ошибке.