Документация по шаблонизатору Fenom

Fenom — это легковесный, быстрый и гибкий шаблонизатор, который становится доступен в modx после установки дополнения pdoTools. Использование данного шаблонизатора не только ускоряет время выполнения запросов, но и еще решает массу повседневных задач, такие как вывод get параметра через fenom в modx, использование условия вывода, циклы и многое другое.

MODXFenomОписание
[[+pagetitle]]{$pagetitle}Заголовок
[[*pagetitle]]{$modx->resource->pagetitle}Заголовок
[[%lexicon]]{$modx->lexicon('lexicon')}вывод словарей
[[~[[+id]]]]{$modx->makeUrl($id)}укл на страницу
[[++site_url]]{$modx->config.site_url}настройки modx
[[$chunkName]]{$pdoTools->getChunk('chunkName')} или {include 'chunkName'}чанк
[[!snippetName]]{$modx->runSnippet("pdoResources", ['parents' => 0])}сниппет
[[*id:is=1:then=``:else=``]]{if $id = 1}{else}{/if}if else
[[+pagetitle:modificator]]{$pagetitle | modificator}модификатор
[[+pagetitle:modificator]]{$_modx->placeholders}массив с системными плейсхолдерами

Другие параметры

FenomОписание
{$_modx->placeholders}массив с системными плейсхолдерами
{$_modx->config}массив с системными настройками
{$_modx->context}массив (не объект!) с текущим контекстом
{$_modx->user}массив (не объект!) с текущим пользователем
{$_modx->resource}массив (не объект!) с текущим ресурсом
{$_modx->lexicon}служба загрузки лексиконов
{$_modx->lexicon()}функция для вывода строки из лексикона
{$_modx->runSnippet()}запуск сниппета
{$_modx->runProcessor()}запуск процессора
{$_modx->getChunk()}вывод чанка
{$_modx->runSnippet('!pdoResources')}не кэшируемый
{$.get.test}GET
{$.post.test}POST
{$date|date:"Y"}текущий год
{55|url}Ссылка на документ

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

FenomОписание
{$date | date: "Y"}текущий год
{55| url}Ссылка на ресурс

Подключение наборов параметров

FenomОписание
{$_modx->getChunk('Name@PropertySet')}для чанка
{include 'Name@PropertySet'}
{$_modx->runSnippet('NameName@PropertySet')}для сниппетов
{include 'template:TemplateName@PropertySet'}

Подключение шаблона

FenomОписание
{include 'template:имя шаблона'}подключение шаблона
{include 'имя чанка'}подключение чанка
{include 'имя чанка'}подключение чанка
{block 'content'}контект{/block}расcтановка блоков
{extends 'file:templates/base.tpl'}наследование шаблона

Синтаксис

Синтаксис используемый в Fenom похож на Smarty, но обладает рядом улучшений. Все теги шаблонизатора заключаются в фигурные скобки: { — открытие тега и } — закрытие тега.

Зачастую, во время первого использования феном на рабочем сайте возникает такая ошибка, как выводится не результат запроса на fenom, а текст кода, это в большинстве случаев связано с тем что в коде javascript также присутствуют фигурные скобки, для решения данной проблемы достаточно обернуть все скрипты между тегами {ignore} ваши скрипты {/ignore}.

Системные переменные

Безымянная системная переменная начинается с $. и предоставляет доступ к глобальным системным переменным и системной информации:

  • $.env — массив $_ENV.
  • $.get — массив $_GET.
  • $.post — массив $_POST.
  • $.files — массив $_FILES.
  • $.cookie — массив $_COOKIE.
  • $.server — массив $_SERVER.
  • $.session — массив $_SESSION.
  • $.globals — массив $GLOBALS.
  • $.request — массив $_REQUEST.
  • $.tpl.name возвращает текущее название шаблона.
  • $.tpl.basename возвращает текущее название шаблона без схемы.
  • $.tpl.scm возвращает схему шаблона.
  • $.tpl.options возвращает параметры шаблона в виде целого числа.
  • $.tpl.depends возвращает массив шаблонов, на которые ссылается текущий шаблон.
  • $.tpl.time возвращает штамп времени, когда шаблон последний раз менялся
  • $.version возвращает версию Fenom.
  • $.const обращение к PHP константе: $.const.PHP_EOL обращение к константе PHP_EOL. Поддерживается пространство имен которое разделяется через точку: $.const.Storage.FS::DIR_SEPARATOR обращение к PHP константе Storage\FS::DIR_SEPARATOR если такой константы нет будет взята константа Storage\FS\DIR_SEPARATOR.
  • $.call обращение к статическомому методу. $.call.Storage.FS::put($filename, $data) обращение к методу Storage\FS::put($filename, $data). Настройка disable_call отключает возможность обращения к $.call. Так же можно ограничить и указать список доступных к вызову классов и функций.
  • $.block проверка на существование блоков которые были определены до момента обращения к акцессору. Например, {$.blocks.BLOCK_NAME}.

Так же вы можете добавить свои или удалить существующие системные переменные и функции

Операции

Как и любой другой язык программирования/шаблонизации, Fenom поддерживает множество различных операторов:

  • Арифметические операторы — +, -, *, /, %
  • Логические операторы — ||, &&, !$var, and, or, xor
  • Операторы сравнения — >, >=,<, <=, ==, !=, !==, <>
  • Битовые операторы — |, &, , ~$var, >>,<<
  • Операторы присвоения — =, +=, -=, *=, /=, %=, &=, |=, =, >>=,<<=
  • Строковый оператор — $str1 ~ $str2
  • Тернарные операторы — $a ? $b : $c, $a ! $b : $c, $a ?: $c, $a !: $c
  • Проверяющие операторы — $var?, $var!
  • Оператор тестирование — is, is not
  • Оператор содержания — in, not in

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

Модификаторы переменных могут быть применены к переменным, пользовательским функциям или строкам. Для их применения надо после модифицируемого значения указать символ | (вертикальная черта) и название модификатора. Так же модификаторы могут принимать параметры, которые влияют на их поведение. Эти параметры следуют за названием модификатора и разделяются: (двоеточием). Кроме того, по умолчанию все функции PHP могут быть использованы в качестве модификаторов (что можно отключить в настройках) и модификаторы можно комбинировать.

{"User" | upper}                    выведет "USER"
{"User" | lower}                    выведет "user"
{'{"User" | lower}'}                выведет "user"
{"User" | lower}}                   выведет "user"
{$looong_text | truncate:80:"..."}  обрежет текст до 80 символов и добавит символы "..."
{set $foo="User" | upper}           значение переменной $foo будет "USER"
{'' | date : 'Y'}                   вывысти текущий год
{1 | resource: 'name'}              получение значения полей ресурса с ID 1 (pagetitle, tv и т.д.)
{$_modx->resource.publishedon | date_format:"%d-%m-%Y %H:%M:%S"}    модификатор дата

Игнорирование кода

Как уже говорилось ранее, если требуется вывести текст, содержащий фигурные скобки, то есть следующие варианты это сделать:

Использование блочного тега {ignore}{/ignore}. Текст внутри этого тега текст не компилируется шаблонизатором и выводится как есть. Если после открывающей фигурной скобки есть пробельный символ (пробел или \t) или перенос строки (\r или \n), то она не воспринимается как разделитель кода Fenom и код после неё выводится как есть. Установить опцию:ignore у блочного тега. Все Fenom теги внутри блока будут проигнорированны

Код:

{ignore}

h1 {font-size: 24px; color: #F00;}

{/ignore}
[removed]
(function (text) {
var e = document.createElement('P');
e[removed] = text;
document.body.appendChild(e);
})('test');
{if:ignore $cdn.yandex}
var item = {cdn: "//yandex.st/"};
{/if}
[removed]

Результат

h1 {font-size: 24px; color: #F00;}

[removed]
(function (text) {
  var e = document.createElement('P');
  e[removed] = text;
  document.body.appendChild(e);
})('test');
var item = {cdn: "//yandex.st/"};
[removed]

Пробелы

Шаблонизатор допускает любое количество пробелов или переносов строк в своём коде

{include 'control.tpl'
  $options = $list
  $name    = $cp.name
  $type    = 'select'
  isolate  = true
  disable_static = true
}

{foreach [
  "one"  => 1,
  "two"  => 2,
  "three" => 3
] as $key  => $val}

{$key}: {$val}

{/foreach}

Fenom в modx

Для использования более сложных сущностей, в pdoParser предусмотрена служебная переменная {$_modx}, которая даёт безопасный доступ к некоторым переменным и методам системы.

  • {$_modx->resource.id} - вывод id ресурса
  • {$_modx->resource.tv_name} - вывод тв ресурса
  • {$_modx->makeUrl(7)} - ссылка на 7 ресурс
  • {$_modx->makeUrl($_modx->resource.id)} - ссылка на текущий ресурс
  • {$_modx->config.system_setting} - вывод системной настройки
  • {$_modx->user}- массив текущего пользователя

Плейсхолдеры с точкой или тире

Во многих местах MODX используются плейсхолдеры, которые нельзя указывать в Fenom, так как они не соответствуют правилам наименования переменных PHP. Например, плейсхолдеры с точкой (MODX обычно выставляет так данные массивов) или с тире (ТВ параметры).

Для доступа к этим плейсхолдерам нужно использовать вторую служебную переменную - {$_pls}:

{$_pls['tag.subtag']}
{var $tv_name = $_pls['tv-name']}
{$tv_name}

Также существуют другие способы вывода плейсхолдеров в modx через fenom, такие как:

{$_modx->getPlaceholder('namePlaceholder')}
{'namePlaceholder' | placeholder}

Примеры работы

// загрукзка ресурсов
{$_modx->runSnippet('pdoResources', [
    'parents' => 19,
    'depth' => 0,
    'where' => ['isfolder' => 0],
    'showLog' => 1,
])}

// загрукзка меню
{$_modx->runSnippet('pdoMenu', [
    'parents' => 0,
    'level' => 2
])}

<p>
{$_modx->lexicon->load('ms2gallery:default')}
    Проверка словарей ms2Gallery: {$_modx->lexicon('ms2gallery_err_gallery_exists')}
</p>

<p>
{if $_modx->isAuthenticated('web')}
    Привет, {$_modx->user.fullname}!
{else}
    Вам нужно авторизоваться =(
{/if}
</p>
<p>Текущий контекст: {$_modx->context.key}</p>

Создание значения из переменной с добавление префикса

{set $lexicon = "ms2_product_{$field}"}
{('ms2_product_' ~ $name) | lexicon}

Тег {foreach}

Тег foreach предоставляет простой способ перебора массивов. Foreach работает только с массивами, объектами и интервалами.

{foreach $list [as [$key =>] $value] [index=$index] [first=$first] [last=$last]}
    {* ...code... *}
    {break}
    {* ...code... *}
    {continue}
    {* ...code... *}
{foreachelse}
    {* ...code... *}
{/foreach}

{foreach}

Перебор значений массива $list:

{foreach $list as $value}
    <div>{$value}</div>
{/foreach}

{foreach 1..7 as $value} {* так же хорошо работает и с интервалами *}
    <div>№{$value}</div>
{/foreach}

Перебор ключей и значений массива $list:

{foreach $list as $key => $value}
    <div>{$key}: {$value}</div>
{/foreach}

Получение номера (индекса) итерации, начиная с 0

{foreach $list as $value}
    <div>№{$value@index}: {$value}</div>
{/foreach}

или

{foreach $list as $value index=$index}
    <div>№{$index}: {$value}</div>
{/foreach}

Определение первой итерации:

{foreach $list as $value}
    <div>{if $value@first} first item {/if} {$value}</div>
{/foreach}

или

{foreach $list as $value first=$first}
    <div>{if $first} first item {/if} {$value}</div>
{/foreach}

Переменная $value@first будет иметь значение TRUE, если текущая итерация является первой. Определение последней интерации:

{foreach $list as $value}
    <div>{if $value@last} last item {/if} {$value}</div>
{/foreach}

или

{foreach $list as $value last=$last}
    <div>{if $last} last item {/if} {$value}</div>
{/foreach}

Переменная $value:last будет иметь значение TRUE, если текущая итерация является последней.

Замечание: Использование last требует от $list быть countable.

{break}

Тег {break} используется для выхода из цикла до достижения последней итерации. Если в цикле встречается тег {break}, цикл завершает свою работу, и далее, выполняется код, следующий сразу за блоком цикла

{continue}

Тег {continue} используется для прерывания текущей итерации. Если в цикле встречается тег {continue}, часть цикла, следующая после тега, не выполняется, и начинается следующая итерация. Если текущая итерация была последней, цикл завершается.

{foreachelse}

Тег {foreachelse} ограничивает код, который должен быть выполнен, если итерируемый объект пуст.

{var $list = []}
{foreach $list as $value}
 <div>{if $last} last item {/if} {$value}</div>
{foreachelse}
 <div>empty</div>
{/foreach}

В блоке {foreachelse}...{/foreach} использование {break}, {continue} выбросит исключение Fenom\CompileException при компиляции

Вывод MIGX через fenom

Вывод migx с помощью fenom для текущего ресурса

{var $rows = $_modx->resource.elements | fromJSON}
{foreach $rows as $idx => $row}
    {$row.image}
{/foreach}

где elements имя migx тв.

Вывод migx с помощью fenom для произвольного ресурса

{var $rows = ID | resource : 'elements' | fromJSON}
{foreach $rows as $idx => $row}
    {$row.image}
{/foreach}

где ID id ресурса тв которого нужно вывести, elements имя migx тв.

Ресайз картинок с помощью phpthumbon через fenom

{$img | phpthumbon : "w=220&h=150&zc=1"}

Запускаем сниппеты modx через fenom

Синтаксис вызова сниппета modx через fenom очень простой, вот пример вызова:

{'!pdoPage' | snippet : [
  'element' => 'mSearch2',
  'toPlaceholder' => 'searchResults'
]}

Если требуется вызвать сниппет без кеширования, вызов будет иметь следующий вид:

{'!pdoPage' | snippet}`

Работаем с файловой системой в modx через fenom

В modx выводить сниппеты, чанки, шаблоны можно не только из бд modx, можно загружать статичные файлы с хостинга с помощью fenom. Для этого по умолчанию в настройках pdoTools указана директория core/elements в которой следует распологать ваши php,tpl и html файлы. Заметим, что статические сниппеты это не совсем modx сниппеты, при возникновении проблемы с работой modx объектов чаще всего помогает наследование переменной modx и pdoTools, для этого в php файл добавьте следующий код:

global $modx;
$pdoTools = $modx->getService('pdoTools');

Вывод статических чанков в modx через fenom

Для этого в директории core/elements/chunks (если такой директории нет, то нужно создать через ftp или ssh, тут уже как вам удобнее) создаем файл (доступны расширения файлов html, htm, tpl) в котором будем хранить html код, для примера назовем файл test.tpl. Для вывода статического чанка на страницу используем одну из следующих команд:

{include 'file:chunks/test.tpl'}
или
{'@FILE chunks/test.tpl' | chunk}

Вывод статических шаблонов в modx через fenom

Вывод шаблонов аналогичен чанкам с тем лишь отличием, что файлы шаблонов для удобства располагаем в директории core/elements/templates и для каждого шаблона в панеле администратора создаем шаблон внутрь которого вставляем код:

{include 'file:templates/test.tpl'}
или
{'@FILE templates/test.tpl' | chunk}

где test.tpl название статического файла размещенного внутри директории templates.

Вывод статических сниппетов в modx через fenom

Для этого в директории core/elements/snippets (если такой директории нет, то нужно создать) создаем файл в котором будет находиться исполняемый php код, например создадим файл test.php в котором будет находиться следующий код <?php echo 'hello world'; и сохраняем файл. Для вывода результата выполнения данного сниппета используем следующий код:

{'@FILE snippets/test.php' | snippet }

Если код написан без ошибок, то выведется hello world иначе скорее всего вы увидите белый экран, в этом случаем проверьте корректность написанного кода, а также смотрите системные логи.

Проверка авторизации

Так как объекта с пользователем в {$_modx} нет, методы проверки авторизации и прав доступа вынесены непосредственно в класс:

{$_modx->isAuthenticated()}
{$_modx->hasSessionContext('web')}
{$_modx->hasPermission('load')}