Fenom в MODX (шпаргалки) / Другое / Фреймворки. Modx if fenom
Шаблонизатор Fenom. Что это и как им пользоваться
Fenom — удобный шаблонизатор кода, поставляющийся вместе с пакетом pdoTools.
Достоинства
Работает быстрее чем родной парсер MODX — modParser;
Недостатки
Конфликтует с фигурными скобками в контенте. Надо учитывать это при проектировании архитектуры сайта, чтобы не гадать в последствии «почему новая статья ломает сайт?».
Системные настройки
- pdotools_fenom_default — включает обработку через Fenom чанков pdoTools. Включено по умолчанию.
- pdotools_fenom_parser — включает обработку шаблонизатором всех страниц сайта. То есть, не только чанков, но и шаблонов.
- pdotools_fenom_php — включает поддержку PHP функций в шаблонизаторе. Очень опасная функция, так как любой менеджер получит доступ к PHP прямо из чанка.
- pdotools_fenom_modx — добавляет системные переменные {$modx} и {$pdoTools} в шаблоны Fenom. Тоже очень опасно — любой менеджер может управлять объектами MODX из чанков.
- pdotools_fenom_options — JSON строка с массивом настроек согласно официальной документации. Например: {"auto_escape":true,"force_include":true}
- pdotools_fenom_cache — кэширование скопмилированных шаблонов. Имеет смысл только для сложных чанков на рабочих сайтах, по умолчанию отключено.
- pdotools_fenom_save_on_errors — сохраняет ошибки компиляции Fenom в специальный файл, для последующей отладки.
Синтаксис
Комментарии для шаблонизатора Fenom:
Теги MODX
Простой вызов
MODX | Fenom |
[[+id]] | {$id} |
[[+id:default=`test`]] | {$id ?: 'test'} |
[[+id:is=``:then=`test`:else=`[[+pagetitle]]`]] | {$id == ''? 'test': $pagetitle} |
{$_modx} — безопасный доступ к переменным и методам системы
[[*id]] | {$_modx->resource.id} |
[[*tv_param]] | {$_modx->resource.tv_param} |
[[%lexicon]] | {$_modx->lexicon('lexicon')} |
[[~15]] | {$_modx->makeUrl(15)} |
[[~[[*id]]]] | {$_modx->makeUrl($_modx->resource.id)} |
[[++system_setting]] | {$_modx->config.system_setting} |
{$_modx->config} — системные настройки
{$_modx->config.site_name} {$_modx->config.emailsender} {$_modx->config['site_url']} {$_modx->config['any_system_setting']}{$_modx->user} — массив текущего пользователя. Если он авторизован, то добавляются и данные из профиля:
{if $_modx->user.id > 0} Привет, {$_modx->user.fullname}! {else} Вам нужно авторизоваться. {/if} {$_modx->context} — массив с текущим контекстом Вы находитесь в контексте {$_modx->context.key} {$_modx->resource} — массив с текущим ресурсом {$_modx->resource.id} {$_modx->resource.pagetitle} {$_modx->makeUrl($_modx->resource.id)} {$_modx->lexicon} — объект (не массив!) modLexicon, который можно использовать для загрузки произвольных словарей: {$_modx->lexicon->load('ms2gallery:default')} Проверка словарей ms2Gallery: {$_modx->lexicon('ms2gallery_err_gallery_exists')}{$_pls} — вывод плейсхолдеров с точкой
Fenom использует точку для доступа к значению массива, а MODX обычно выствляет так плейсхолдеры из массивов. Соотвественно, для тегов аналогов в Fenom не предусмотрено.Поэтому для подобных плейсхолдеров необходимо использовать вторую служебную переменную — {$_pls}:
{$_pls['tag.subtag']} Например вывод доп поля со стандартным префиксом tv. {$_pls['tv.img']}Переменные
Если надо установить переменную, не выводя ее результат, используются тег {set} (в старом синтаксисе {var})
{set $var=(expr)} {set $var} ... any content ... {/set} {set $var|modifiers} ... any content ... {/set} {set $v = 5} {set $v = "value"} {set $v = $x+$y} {set $v = 4} {set $v = $z++ + 1} {set $v = --$z} {set $v = $y/$x} {set $v = $y-$x} {set $v = $y*$x-2} {set $v = ($y^$x)+7} {set $v = [1,2,3]} {set $v = []} {set $v = ["one"|upper => 1, 4 => $x, "three" => 3]} {set $v = ["key1" => $y*$x-2, "key2" => ["z" => $z]]} {set $v = count([1,2,3])+7} // В качестве значения переменной можно задать результат отрисовки фрагмента шаблона {set $v} Some long {$text|trim} {/set} // применение модификатора к данным перед тем как они будут сохранены в переменную {set $v|escape} {* применение можификатора к значению *} Some long {$text|trim} {/set}Тег {add} делает тоже самое что и тег {set} за исключением того что сначала проверяет наличие переменной и если переменной нет — задет новое значение.
{add $var = 'value'} // схема работы тега {if $var is not set} {set $var = 'value'} {/if}Условия
{if $idx == 1} idx = 1 {elseif $idx == 4} idx = 4 {/if} {switch $idx} {case 1} idx=1 {case 4} idx=4 {default} idx = $idx {/switch }Вывод сниппетов и чанков
{$_modx->runSnippet('!pdoPage@PropertySet', [ 'parents' => 0, 'showLog' => 1, 'element' => 'psoResources', 'where' => ['isfolder' => 1], 'showLog' => 1, ])} {$_modx->getPlaceholder('page.total')} {$_modx->getPlaceholder('page.nav')}По умолчанию все сниппеты вызываются кэшированными, для некешированного вызова добавляется ! — как и в тегах MODX.
Для вывода чанков запускается pdoTools, можно использовать все его возможности:
{$_modx->getChunk('MyChunk@PropertySet')} {$_modx->parseChunk('MyChunk', [ 'pl1' => 'placeholder1', 'pl2' => 'placeholder2', ])} {$_modx->getChunk('@TEMPLATE Base Template')} {$_modx->getChunk('@INLINE Имя сайта: {$_modx->config.site_name} ')} {$_modx->getChunk( '@INLINE Передача перемнной в чанк: {$var}', ['var' => 'Тест'] )} {$_modx->getChunk(' @INLINE Передача переменной в вызов сниппета: {$_modx->runSnippet("pdoResources", [ "parents" => $parents ])} Всего результатов: {$_modx->getPlaceholder("total")} ', ['parents' => 0] )}Управление кэшированием
В объекте {$_modx} доступен сервиc modX::cacheManager, который позволяет устанавливать произвольное время кэширования вызываемых сниппетов: {if !$snippet = $_modx->cacheManager->get('cache_key')} {set $snippet = $_modx->runSnippet('!pdoResources', [ 'parents' => 0, 'tpl' => '@INLINE {$id} - {$pagetitle}', 'showLog' => 1, ])} // set $null — чтобы cacheManager->set не вывел 1 (т.е. true) на страницу {set $null = $_modx->cacheManager->set('cache_key', $snippet, 1800)} // 30 минут {/if} {$snippet}Посмотреть этот кэш можно в /core/cache/default/
Системные процессоры
Можно запускать системные процессоры (если хватит прав ):
{$_modx->runProcessor('resource/update', [ 'id' => 10, 'alias' => 'test', 'context_key' => 'web', ])}Проверка авторизации
Так как объекта с пользователем в {$_modx} нет, методы проверки авторизации и прав доступа вынесены в классы: {$_modx->isAuthenticated()} // если авторизован {$_modx->hasSessionContext('web')} // есть ли доступ к контексту {$_modx->hasPermission('load')} // есть ли праваОстальные методы
{$_modx->regClientCss('/assets/css/style.css')} // регистрация css {$_modx->regClientScript('/assets/css/script.js')} // регистрация js {$_modx->sendForward(10)} // загрузить ресурс без изменения url {$_modx->sendRedirect('http://yandex.ru')} // перенаправление, редирект {$_modx->setPlaceholder('key', 'value')} // установить плейсхолдер {$_modx->getPlaceholder('key')} // получить плейсхолдер {if $res = $_modx->findResource('url-to/doc/')} // найти ресурс {$_modx->sendRedirect( $_modx->makeUrl($res) )} // создать url {/if}Расширение шаблонов
Использование шаблонизатора Fenom позволяет включать одни чанки (шаблоны в другие) и даже расширять их.
{include} — используются для включения других шаблонов в текущий. Например, можно просто подгрузить содержимое чанка:
Обычный чанк {include 'имя чанка'} Шаблон modTemplate {include 'template:имя шаблона'} Чанк с набором параметров {include 'chunk@propertySet'} {include 'template:Name@propertySet'}{include} в официальной документации
{extend} — возможность подключения шаблона или чанка для последующего его расширения.
требует включенной системной настройки pdotools_fenom_parser.
Пример: базовый шаблон «Fenom Base» включает обычные чанки и определяет несколько блоков {block}, которые можно расширить в другом шаблоне:
<!DOCTYPE html> <html lang="en"> <head> {include 'head'} </head> <body> {block 'navbar'} {include 'navbar'} {/block} <div> <div> {block 'content'} {$_modx->resource.content} {/block} </div> <div> {block 'sidebar'} Sidebar {/block} </div> {block 'footer'} {include 'footer'} {/block} </div> </body> </html>Дочерний шаблон «Fenom Extended», в котором подключается «Fenom Base» и расширяется блок content:
{extends 'template:Fenom Base'} {block 'content'} <h4>{$_modx->resource.pagetitle}</h4> <div> {parent} </div> {/block}Также можно расширять чанки, но, для чанков не нужен префикс template.
{extends} в официальной документации
www.riwkus.pro
Шпаргалка по Fenom | Блог bustep
[[+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} | массив с системными плейсхолдерами |
Другие параметры
{$_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"} | текущий год |
Подключение наборов параметров
{$_modx->getChunk('Name@PropertySet')} | для чанка |
{include 'Name@PropertySet'} | |
{$_modx->runSnippet('NameName@PropertySet')} | для сниппетов |
{include 'template:TemplateName@PropertySet'} |
Подключение шаблона
{include 'template:имя шаблона'} | подключение шаблока |
{include 'имя чанка'} | подключение чанка |
{block 'content'}контект{/block} | растановка блоков |
Примеры работы
// загрукзка ресурсов {$_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 $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 при компиляции
bustep.ru
Fenom в MODX (шпаргалки) / Другое / Фреймворки – MODX.ONE
Fenom — это быстрый и удобный шаблонизатор, который очень схож со Smarty (в плане синтаксиса), но является намного лучше! С его помощью Вы можете ускорить разработку, время на выполнение запросов, сократить количество чанков, использовать циклы прям в чанках/шаблонах и многое другоеВ MODX Fenom появился в 2015 году, с выходом обновления pdoTools 2.0. Теперь когда вы устанавливается pdoTools, парсер Fenom уже активен, но не обрабатывает страницы и шаблоны сайта
Для того, чтобы включить fenom (обработку страниц и шаблонов сайта), необходимо активировать параметр pdotools_fenom_parser в системных настройках.
Синтаксис
Можете посмотреть официальную документацию, а я буду рассматривать синтаксис, касательно MODX Revolution.
Итак, как я уже говорил, синтаксис довольно прост, вместо привычных двойных квадратных скобок в MODX
[[ ]] и Fenom используются одинарные фигурные скобки { }Чтобы использовать более сложные функции, в pdoParser есть служебная переменная {$_modx}, которая даёт безопасный доступ к некоторым переменным и методам системы.- {$_modx->resource.id} — вывод id текущего ресурса
- {$_modx->resource.tv_name} — вывод tv текущего ресурса
- {$_modx->user} — массив текущего пользователя
- {$_modx->makeUrl(10)} — ссылка на 10 ресурс
- {$_modx->config.system_setting} — вывод системной настройки
Игнорирование кода
Так как в Fenom используются фигурные скобки, то возможно возникнет такая проблема, что не будут выполняться какие-то скрипты/стили.Для этих случаев существует переменная ignore. Для того, чтобы выключить обработку Fenom необходимо просто обернуть скрипты/стили в этот тег:
<style> {ignore} body {font-size: 16px; background-color: #000;} {/ignore} </style>Плейсхолдеры с точкой или тиреВ MODX как вы знаете существуют TV параметры у ресурса или плейсхолдеры с точкой (данные массивов). Так как они не соответсвуют правилам наименования, то в Fenom для доступа к плейсхолдерам и TV существуют служебная переменная {$_pls}
<!-- Вывод сразу --> {$_pls['tag.subtag']} <!-- Или через переменную --> {var $tv_name = $_pls['tv-name']} {$tv_name}Как запустить сниппет в Fenom?Я знаю два способа, как запустить сниппет в Fenom, какой использовать, решать только Вам.
1 способ:
{'!pdoPage' | snippet : [ 'parents' => $_modx->resource.id, 'limit' => 5, 'toPlaceholder' => 'result' ]}{$_modx->getPlaceholder('result')} {$_modx->getPlaceholder('page.total')} {$_modx->getPlaceholder('page.nav')}2 способ:{$_modx->runSnippet('!pdoPage', [ 'parents' => $_modx->resource.id, 'limit' => 5, 'toPlaceholder' => 'result' ])}{$_modx->getPlaceholder('result')} {$_modx->getPlaceholder('page.total')} {$_modx->getPlaceholder('page.nav')}Если необходимо вызвать pdopage без параметров:#1 способ {'!pdoPage' | snippet} #2 способ {$_modx->runSnippet('!pdoPage')}Примеры использования Fenom MODX:Условие IF
#Устанавливаем id текущей страницы в переменную {set $id = $_modx->resource.id} #Условие {if $id == '1'} <p>Главная страница</p> {else} <p>Не главная</p> {/if}Условие IF с использованием тренарного оператора#Устанавливаем id текущей страницы в переменную {set $id = $_modx->resource.id} #Условие {$id == '1' ? '<p>Главная страница</p>' : '<p>Не главная</p>'}Вывод чанка{include 'myChank'}Получение значения TV у произвольного ресурса:{1 | resource: 'tv_name'}*1 — id ресурсаВывод MIGX через Fenom для текущего ресурса:
{set $rows = json_decode($_modx->resource.tv_images, true)} {foreach $rows as $row} {$row.image} {/foreach}Информация о прозводителе в miniShop2{$_modx->makeUrl($_pls['vendor.resource'])} {$_pls['vendor.name']}) {$_modx->getPlaceholder('vendor.name')}Получение изображения через переменную с точкой ($_pls){$_pls["tv.img"] | phpthumbon : "w=300&h=200&zc=1"} //Без префикса {$img | phpthumbon : "w=300&h=200&zc=1"}Получение превью изображений в корзине{if $product['120x90']?} <img src="{$product['120x90']}" alt="{$product.pagetitle}" title="{$product.pagetitle}"/> {else} <img src="{'assets_url' | option}components/minishop2//web/ms2_small.png" alt="{$product.pagetitle}" title="{$product.pagetitle}"/> {/if}Модификатор дата{$_modx->resource.publishedon | date_format:"%d-%m-%Y %H:%M:%S"}Вывысти текущий год{'' | date : 'Y'}Проверка авторизации{$_modx->isAuthenticated()} {$_modx->hasSessionContext('web')} {$_modx->hasPermission('load')}test.modx.one
Поля ресурса (Resource Fields) | [[*pagetitle]] | {$_modx->resource.pagetitle} |
Переменные шаблона (Template Variables) | [[*tag]] | {$_modx->resource.tag} |
Словари (Lexicon) | [[%link_contacts]] | {$_modx->lexicon('link_contacts')} или {'link_contacts' | lexicon} |
Ссылки (links) | [[~12]] [[~[[*id]]]] | {$_modx->makeUrl(12)}{$_modx->makeUrl($_modx->resource.id)} |
Системные настройки (System settings) | [[++access_category_enabled]] | {$_modx->config.access_category_enabled} или {'access_category_enabled' | config} или {$_modx->config['access_category_enabled']} |
Плейсхолдеры (Placeholders) | [[+image]] | {$_modx->getPlaceholder(image)} или {$image} |
Плейсхолдеры с точкой или тире | [[+tag.subtag]] | {$_pls['tag.subtag']} |
Комментарии (Comments) | [[- Это комментарий]] | {* Это комментарий *} |
Игнорирование кода с круглыми скобками | {ignore} {/ignore} | |
Чанки (Chunks) | [[$chunk]] | {$_modx->getChunk('chunk')} или {include 'chunk'} |
Сниппеты (Snippets) | [[!pdoMenu? &parents=`0` &level=`0`]] | {$_modx->runSnippet('!pdoMenu', ['parents'=>'0','level'=>'0'])} или {'!pdoMenu' | snippet:['parents'=>'0','level'=>'0']} |
{$_modx->isAuthenticated()} | {$_modx->hasSessionContext('web')} | {$_modx->hasPermission('load')} |
{$_modx->user} | Массив с информацией о пользователе | {$_modx->user | print_r} |
{$_modx->context} | Массив с информацией о контексте | {$_modx->context | print_r} |
{$_modx->resource} | Массив с информацией о текущем ресурсе | {$_modx->resource | print_r} |
{$_modx->lexicon} | Объект modLexicon, который можно использовать для загрузки произвольных словарей | |
{$_modx->regClientCss('/assets/css/style.css')} | Подключение css файла | |
{$_modx->regClientScript('/assets/css/script.js')} | Подключение js файла | |
{$_modx->sendForward(1)} | Загрузка ресурса без изменения ссылки | |
{$_modx->sendRedirect('http://modx.ru')} | Перенаправление на страницу | |
{$_modx->setPlaceholder('name', 'Ivan')} | Сохранение плейсхолдера | |
{$_modx->toPlaceholder('name', 'Ivan','my')} | Сохранение плейсхолдера с префиксом | |
{$_modx->toPlaceholders(['city' => 'Moscow', 'man' => ['name' => 'Ivan', 'surname' => 'Ivanov']],'my')} | Предает многоуровневый массив в плейсхолдер | |
{$_modx->setPlaceholders(['name' => 'Ivan', 'surname' => 'Ivanov'])} | Сохранение массива плейсхолдеров | |
{$_modx->getPlaceholder('name')} | Получение значения плейсхолдера | |
{$_modx->getPlaceholders()} | Получение списка плейсхолдеров | |
{$_modx->unsetPlaceholder('name')} | Удаление плейсхолдера по ключу | |
{$_modx->unsetPlaceholders(['name', 'surname'])} | Удаление плейсхолдера по массиву ключей | |
{$_modx->regClientStartupScript('//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js')} | Добавление js файла перед закрытием тега head | |
{$_modx->regClientStartupHTMLBlock('<strong>Привет мир</strong>')} | Добавление тегов перед закрытием тега head | |
{$_modx->regClientHTMLBlock('<div>(c) 2009 MODx</div>')} | Добавление тегов перед закрытием тега body | |
{$_modx->runProcessor('resource/update', ['id' => 10,'alias' => 'test','context_key' => 'web'])} | Запуск системного процессора | |
{$_modx->hasPermission('edit_chunk')} | Возвращает true, если пользователь имеет доступ к политике | |
{$_modx->isMember('Marketing')} | Проверяет, принадлежит ли пользователь группе | |
{$_modx->findResource('url-to/doc/')} | Возвращает true если ресурс найден | |
{$_modx->sendError('unavailable')} | Отправляем ошибку пользователю и прекращаем работу скрипта | |
{$_modx->getInfo()} | Информация о скорости загрузки | |
{$_modx->getChildIds(23,6,['context' => 'web']} | Получаем список идентификаторов дочерних ресурсов | |
{$_modx->getParentIds(23,6,['context' => 'web']} | Получаем список идентификаторов родительских ресурсов, которым принадлежит данный ресурс | |
{$_modx->->getResource(1)} | Получаем массив информации о текущем ресурсе по его id | |
{$_modx->getResources(['published' => 1, 'deleted' => 0])} | Получаем массив ресурсов | |
{$_modx->cleanAlias()} | Генерация псевдонима |
www.webapplex.ru
Fenom для MODX - базовые понятия и примеры – Веб мастерская Привилегия
Шаблонизатор Fenom – это надстройка для MODX Revo, включённая в состав пакета pdoTools. Позволяет полностью заменить "родные" теги MODX с увеличением скорости и удобства работы с информацией из таблиц базы данных и значительно расширить возможности шаблонизации.
Для тех, кто начинал изучение MODX по официальной документации, поначалу работа с Fenom может показаться неудобной и более сложной, а, открыв первый раз сайт на Fenom, вообще не сообразить, что и как работает.
Это быстро проходит) и, возвращаясь при необходимости к стандартным тегам, начинает не хватать возможностей парсера pdoTools.
Включение Fenom
Для того, чтобы теги Fenom начали обрабатываться в шаблонах, чанках и тексте ресурса, нужно включить следующие настройки: Системные настройки - pdotools:
Шаблонизатор имеет такую особенность – если парсер не может обработать страницу, она может выйти пустой, либо с исходными тегами. Причина пишется в Журнале ошибок. Первоначально, нужно обратить внимание на инлайновые стили и скрипты Java, потому что парсер срабатывает на фигурные скобки {}.
Для указания парсеру Fenom фрагментов, не подлежащих обработке, используются теги {ignore}фрагмент{/ignore}. Помогает не всегда, это связано с особенностями работы парсера. Часто бывает проще расставить пробелы или переносы строки после открывающей скобки и перед закрывающей.
Базовые понятия
Основные источники информации по работе с Fenom – в документации modx.pro и в исходной документации.
Желательно сразу освоить файловые элементы (официальное руководство).
Начнём с шаблонов. По умолчанию, путь к файлам core/elements(папку elements нужно будет создать). Дальше, на усмотрение, кому как удобно.
Например, создадим папки templates, chunks и snippets(в директории elements, понятное дело). Пускай базовый шаблон будет main.html(или с расширением tpl, неважно). Весь текст, соответственно, будет храниться в файле core/elements/templates/main.html.
Для связи со структурой MODX нужно будет создать обычным способом шаблон, в поле Код шаблона которого записывается ссылка на файл в виде {include 'file:templates/main.html'}.
Чанки и сниппеты в админ панели создавать не нужно. Файловый чанк прописывается в шаблоне через include – {include 'file:chunks/header.html'}, запуск сниппета из файла – {'@FILE snippets/cache.php' | snippet}.
В шаблонах и чанках нежелательно мешать теги Fenom со стандартными тегами, поскольку в этом случае запускается встроенный парсер MODX.
Как работает наследование и расширение шаблонов (чанков) в Minishop2 можно увидеть на примере чанков писем. Здесь 6 видов оповещений построены на 1 базовом шаблоне.
Аналоги тегов MODX
Поля текущего ресурса (теги со *): {$_modx->resource.id}, {$_modx->resource.pagetitle}, {$_modx->resource['description']}, либо {$_modx->resource['имя_тв_поля']} и т.д. (разные варианты обращения к элементам массива $_modx->resource).
Плейсхолдеры сниппета (теги с +): {$id}, {$longtitle}
Системные настройки (теги с ++): {'site_url' | option} или {$_modx->config['site_url']}
Ссылка на ресурс (теги с ~): {88 | url}. Например, генерация абсолютной ссылки на документ с id = 88, [[++site_url]][[~88]] = {'site_url' | option ~ (88 | url)} или {'site_url' | option}{88 | url)} (в Fenom символ ~ выполняет объединение строк)
Поля любого ресурса: {11 | resource : 'longtitle'}
Вызов сниппета: {'pdoSitemap' | snippet}, некешированный {'!pdoSitemap' | snippet}, с параметрами {'!pdoMenu' | snippet : ['parents' => 0, 'resources' => '-1,-6', 'showHidden' => 1]}
Поля любого пользователя по его id: {5 | user : 'fullname'}
Массив полей текущего пользователя $_modx->user. Например, посмотреть все поля {$_modx->user | print}
Закомментировать теги Fenom можно так: {*'!pdoPage' | snippet*}
Разумеется, это не все возможности шаблонизатора, есть ещё масса модификаторов, полностью заменяющих "родные" теги MODX и расширяющие их функции.
Условия и циклы
Это как раз то, что меняет подход к построению страницы сайта. При всём уважении, условия в стандартном синтаксисе MODX, в особенности вложенные, напоминают фразу из "Собачьего сердца": "Кто на ком стоял??? Потрудитесь излагать Ваши мысли яснее."
Условия в Fenom задаются так же, как в большинстве языков программирования:
условие if:
{if $_modx->resource.parent == 1} {$_modx->resource.pagetitle} {elseif $_modx->resource.parent == 5} {$_modx->resource.longtitle} {else} Другой текст заголовка {/if}использование логических И (&&), ИЛИ (||) и группировка условий (тут же пример присвоения значения переменной):
{var $u = 5}{var $e = 9} {if $u > 2 || ($e >= 3 && $eкороткая запись if (тернарный оператор),
{$_modx->resource.longtitle ? $_modx->resource.longtitle : $_modx->resource.pagetitle}или аналог стандартного default в случае пустого значения:
{$_modx->resource.introtext ?: 'аннотация не заполнена'}условие switch:
{switch $_modx->resource.id} {case 5} Текст {case 7,8} Другой текст {case default} Пусто {/switch}Полноценный цикл foreach:
{var $array = [0 => 'val1', 1 => 'val2']} {foreach $array as $key => $value} key = {$key}, value = {$value} {/foreach}Пример вывода ресурсов без вызова сниппета
В Fenom переменная $_modx – обращение к классу microMODX, имеющему несколько очень полезных методов.
перенаправление на заданный url, либо ресурс (здесь, с id = 101) {$_modx->sendRedirect(101 | resource : 'uri')}
получение потомков документа (здесь, id документа 47, глубина вложенности 1). Поскольку возвращает массив, для наглядности показан с простым выводом на экран. {$_modx->getChildIds(47, 1) | print}
То же, для родителей документа $_modx->getParentIds()
Получение масивов полей ресурсов без сниппета и вывод без чанка:
{var $parents = $_modx->getResources( ['published' => 1, 'deleted' => 0, 'isfolder' => 1], ['sortby' => 'menuindex', 'select' => 'id,pagetitle'])} {foreach $parents as $parent} {var $childs = $_modx->getResources( ['published' => 1, 'deleted' => 0, 'parent' => $parent.id], ['select' => 'pagetitle', 'sortby' => 'menuindex'])} {if $childs} <div> <h5>{$parent.pagetitle}</h5> {foreach $childs as $child} <div> {$child.pagetitle} </div> {/foreach} </div> {/if} {/foreach}Этот пример показывает, как, пользуясь только средствами Fenom, вывести ресурсы, сгруппированные по родительскому документу.
my-priv.ru
Помогите с Fenom / modx.pro
Друзья, помогите пожалуйста! Разбираюсь с Fenom, нужно пару подсказок, чтобы мог потихоньку двигаться дальше, надеюсь мои ламерские вопросы и другим помогут.Вопрос 1: как сделать вызов чанка (название чанка берется из ТВ-поля) в такой конструкции:{$_modx->runSnippet('!pdoMenu@PropertySet', [ 'parents' => '2', 'showLog' => 0, 'includeTVs' => 'svg-icon', 'level' => '1', 'tplOuter' => '@INLINE <ul{$classes}>{$wrapper}</ul>', 'tpl' => '@INLINE <li{$classes}> <a href="{$link}" {$attributes}> <div> <div>[[$[[+svg-icon]]]]</div> <div>{$menutitle}</div> </div> </a> </li>', 'outerClass' => 'nav' ])}Такие вызовы здесь не работают: {$_modx->resource.svg-icon}, {$_modx->getChunk('chunk_name')}Вопрос 2: Ниже листинг чанка ms_product_content, все ли здесь правильно и как правильно вызвать конструкцию проверки OLD_PRICE?<h2>{$_modx->resource.longtitle}</h2> <div> <div> {$_modx->runSnippet('!msGallery@PropertySet', [ 'tplEmpty' => 'shop_tpl.msGallery.empty', 'tplOuter' => 'shop_tpl.msGallery.outer', 'tplRow' => 'shop_tpl.msGallery.row', ])} </div> <div> <form method="post"> <input type="hidden" name="id" value="{$_modx->resource.id}"> <div> <label>{$_modx->lexicon('ms2_product_article')}:</label> <div> <label> {$article} </label> </div> </div> <div> <label>{$_modx->lexicon('ms2_product_price')}:</label> <div> <label> {$price} {$_modx->lexicon('ms2_frontend_currency')} {$old_price > '0' ? '<span>[[+old_price]] [[%ms2_frontend_currency]]</span>' : ''} </label> </div> </div> <div> <label for="product_price">{$_modx->lexicon('ms2_cart_count')}:</label> <div> <input type="number" name="count" value="1" /> {$_modx->lexicon('ms2_frontend_count_unit')} </div> </div> <div> <label>{$_modx->lexicon('ms2_product_weight')}:</label> <div> <label>{$weight} {$_modx->lexicon('ms2_frontend_weight_unit')}</label> </div> </div> {$_modx->runSnippet('!msOptions@PropertySet', [ 'name' => 'color', ])} {$_modx->runSnippet('!msOptions@PropertySet', [ 'name' => 'size', ])} {$_modx->runSnippet('-!msOptions@PropertySet', [ 'name' => 'tags', 'tplRow' => '', 'tplOuter' => '', ])} <div> <label>{$_modx->lexicon('ms2_product_made_in')}:</label> <div> <label>{$made_in}</label> </div> </div> <div> <div> <button type="submit" name="ms2_action" value="cart/add"><i></i> {$_modx->lexicon('ms2_frontend_add_to_cart')}</button> </div> </div> </form> </div> </div> {$_modx->runSnippet('!msProductOptions@PropertySet', [ 'hideEmpty' => 1, 'groups' => '11,12,14', 'tplOuter' => 'shop_tpl.msProductOptions.outer', 'tplRow' => 'shop_tpl.msProductOptions.row', ])} <p>{$_modx->resource.introtext}</p> {$_modx->resource.content}modx.pro