ZoomX. Создание плагинов для Smarty
Smarty из коробки содержит несколько модификаторов и кастомных функций. Но, конечно, их не хватит на все случаи в жизни. Поэтому придётся расширять этот список. Делается это через плагины. С помощью них вы можете создать свои модификаторы, функции, блоки, функции для компилятора, фильтры (pre и post) и ресурсы. Подключаются они двумя способами:
- автоматически (Smarty сам подключает нужный файл плагина по требованию);
- динамически (вы сами должны подключить плагин или фильтр через специальные методы registerPlugin() и registerFilter()).
Файловые плагины
Мне кажется, это самый простой способ. Нужно создать файл в папке с плагинами Smarty. У ZoomX уже есть папка плагинов, в которой находятся Smarty плагины для MODX. Можно создавать файлы в ней. Или выбрать другое место. В этом случае необходимо указать этот путь в системной настройке zoomx_custom_plugin_dir
. Но тут есть важная тонкость. Для того, чтобы Smarty его увидел, файл нужно назвать в соответствии с определёнными правилами, описанными в документации — сначала указывается тип плагина (function, modifier, block и т.д.), затем точка, дальше название, которое будет использоваться в шаблоне, и заканчивается всё расширением php. Т.е. для модификатора chunk
это должно выглядеть так — modifier.chunk.php
.
После того, как файл создали, в нём нужно объявить функцию, у которой название также должно формироваться по следующему правилу — smarty_тип плагина_название
. Для нашего примера функция будет называться smarty_modifier_chunk
. Теперь, если модификатор chunk
будет указан в шаблоне, то Smarty автоматически его подгрузит.
Давайте для примера создадим модификатор, который работает как FastField (когда можно вызывать поля указанного ресурса, а не только текущего). Поэтому заглянем в документацию и посмотрим на синтаксис именно для модификаторов.
В Fenom, который подключается pdoTools, тоже есть такой модификатор. Пишется он так {5 | resource : 'pagetitle'}
. В итоге модификатор resource
имеет неоднозначный синтаксис — в одном случае указывается поле текущего ресурса ({'pagetitle' | resource}
), в другом id документа. Соответственно и параметры зависят от режима.
Мы пойдём другим путём — создадим отдельный модификатор. Назовём его коротко — field
. За основу возьмём плагин модификатора resource. Файл назовём соответственно modifier.field.php
. Сама функция получится такой:
<?php /* * Smarty plugin * ------------------------------------------------------------- * Файл: modifier.field.php * Тип: modifier * Имя: field * Назначение: Get a field of the specified resource. * ------------------------------------------------------------- */ function smarty_modifier_field($id, $field) { global $modx; $id = (int)$id; if ($id && $resource = $modx->getObject('modResource', ['id' => $id])) { return $resource->{$field}; } return null; }
Внимание!
Тут важно понимать, что разработчик берёт на себя ответственность за безопасность, так как в данном случае он может открыть данные закрытого ресурса. Поэтому, было бы правильнее делать проверку прав для текущего пользователя. Ну и для случая, если таких модификаторов на странице несколько, ресурс лучше закэшировать.
Ну и теперь вызываем его в шаблоне — получим поле pagetitle ресурса с id=5
.
{5|field:"pagetitle"} // Можно вернуть дефолтное значение {5|field:"pagetitle"|default:"Ресурс не найден!"}
Динамические плагины
Тут уже никакой магии не будет — придётся создать плагин на событие OnModxInit (можно и на OnHandleRequest) и в нём добавить функцию Smarty плагина. Никакие правила именования тут уже не нужны. Для примера добавим тот же модификатор field
.
<?php // Плагин // Событие OnModxInit if ($modx->context->key !== 'mgr') { function fieldModifier($id, $field) { global $modx; $id = (int)$id; if ($id && $resource = $modx->getObject('modResource', ['id' => $id])) { return $resource->{$field}; } return null; } // Регистрируем функцию модификатора $smarty = parserx(); $smarty->registerPlugin("modifier","field", "fieldModifier"); }
Таким же образом можно регистрировать функции, блоки и т.д.
Заключение
Лично мне удобнее первый вариант — раз мы отказались от элементов в БД, то зачем опять начинать. Вся разработка в IDE редакторе. В PhpStorm есть полноценная поддержка Smarty. Поэтому кодить достаточно приятно и удобно.
Комментарии ()
Вы должны авторизоваться, чтобы оставлять комментарии.
Возник вопрос по роутеру ZoomX
Допустим есть такой URL mysite.ru/catalog/segment
Segment может быть как и категорией в каталоге, так и товаром
Вопрос как разрулить и назначить нужные шаблоны по условию?
Я пробую так:
Думал так прокатит, но MODX в этот момент не имеет доступа к текущему ресурсу и определить по какому либо признаку ресурс не получается, чтобы назначить ему нужный шаблон.
Или вообще всю логику в плагин перенести, а в роуте возвращать пустую строку.
Я пока придумал такой велосипед, он как бы возвращает привязку к шаблонам в адимнке и при этом оставляет возможность пользоваться Smarty. Так при любых URL за ресурсом сохранится его шаблон.
В этом случае будет и проверка прав, и запрос документа из кэша (если есть).
Можно ли отключить роутинг и при этом дальше использовать smarty?
Где и как в таком случае нужно указывать привязку шаблонов?
Тут видишь, как начинаешь использовать, сразу возникает много вопросов и интересных предложений. А без использования пока всё в теории. Ребята вроде заинтересовались, но пробовать как-то не торопятся. И у меня планы по переделке этого сайта пока тормозятся. Хотел миникурс на своем примере сделать, но нет времени. Пока присматриваю шаблон для блога.
Есть вопрос по ZoomX — как из роутера можно дать команду передать поиск адреса модексу?
Я по прежнему использую свой велосипед
Но проблема — не знаю как вывести в таком случае ресурсы без шаблонов и с другим типом содержимого.
У меня такими являются robots.txt и sitemap.xml — они генерятся с динамикой в содержании, но как их отдать в браузер не пойму.
Есть какой-то способ прямо в коде роутера сказать — Отдай это модексу, он сам разберётся.
Да уж, велосипед знатный ) Ребята из мира фреймворков много «добрых» слов бы сказали про такую маршрутизацию.
Как я уже писал, флагом запуска шаблонизатора Smarty является наличие роута для адреса запроса. Есть роут — работает функционал ZoomX, нет — работает MODX. Признак выставляется в свойстве Zoomx\Request::hasRoute.
В твоём случае роут всегда срабатывает. Поэтому придётся этот флаг переопределять внутри роута
В этом случае должен сработать MODX.
П.С. Сорян за поздний ответ. Письма о комменте почему-то не было
То, что нужно
П.С. Письма так и не приходят.