[ZoomX] Файловые плагины, markdown, кэширование сниппетов
Привет, друзья! Наконец я выпустил новую версию ZoomX. Эта версия минорная, но в ней много заслуживающего внимания. Расскажу о самом интересном:
Возможно не все знают, но я уже решал эту задачу в своём дополнении Middlewares. В ZoomX я предлагаю доработанную версию файловых плагинов. Давайте познакомимся с ними.
Файловые плагины в отличие от файловых сниппетов представляют собой классы. Вот пример такого плагина.
Как видите, названия методов совпадают с названиями событий. Таким образом, один класс содержит функционал для разных событий в отличие от того же Laravel, где для каждого события создаётся отдельный класс. В свойстве $events указываются события, которые должны сработать. Это добавляет гибкости, так как можно запускать только указанные события. Также плагин можно отключить с помощью свойства $disabled.
Ещё хотелось бы отметить, что данный механизм легко подхватывает файловые элементы компонентов (если авторы их используют).
Тут всё просто. Пригодится для тех, кто привык работать с этим форматом.
Сейчас MODX предлагает следующую логику кэширования — или сниппет никогда не кэшируется или кэшируется с сохранением результата на странице. Т.е. или он будет вызыватся при каждом запросе, или после первого выполнения он будет заменён на результат и больше работать не будет. Но этих вариантов бывает недостаточно. Приходилось писать сниппеты-обёртки, которые сохраняли результат на определённое время. Теперь это можно сделать прямо из коробки. В теге сниппета в атрибуте cache_lifetime нужно указать количество секунд для хранения результата в кэше.
Если все контроллеры находятся в одном пространстве имён, то зачем постоянно их указывать. Теперь в системной настройке zoomx_controller_namespace можно указать неймспейс контроллеров, а в роутах писать только имя класса.
Если для переадресации не нужны никакие проверки, то можно воспользоваться специальным методом redirect маршрутизатора.
Переадресовывать можно и роуты с масками. В URI переадресации нужно указать соответствующую переменную со знаком $ в фигурных скобках.
Данное событие сработает перед вызовом хандлера роута (контроллера или фукнции). В нем можно выполнить определённые проверки и изменить стандартное поведение. Например, можно взять из роута id объекта (ресурса, пользователя и т.д) и в плагине получить соответствущий объект. Таким образом в методе контроллера будет уже не id, а готовый объект.
За доработку этой функции можно поблагодарить @Николай Савин. Для удобства в эту функцию добавлен третий параметр для указания HTTP кода ответа.
Если код статуса будет меньше 400, то свойство success, указывающее об успешности запроса, будет равно true.
Для кода 400 и выше признак успешности будет false, а данные по ошибке будут в свойстве errors:
А если включён обработчик ошибок ZoomX (по-умолчанию включён), то и все ошибки PHP и исключения будут также отдаваться в этом формате.
Ещё в главный сервис была добавлена возможность сохранять данные для последующего использования. Это часть функционала DI контейнера. Это промежуточная ступень к внедрению полноценного DI контейнера если появится потребность.
Сохранить в контейнер
Затем в любом месте приложения можно получить сохранённую переменную.
Я опустил все технические подробности. Кому они интересны прошу сюда.
В общем, пробуйте, пишите чего не хватает, что доработать. У меня самого ещё много планов на этот компонент. И по функционалу и серию уроков снять. Надеюсь, в следующем году их все реализовать. Всех с Наступающим!
- Файловые плагины.
- Модификатор markdown.
- Механизм кэширования сниппетов.
- Короткие имена контроллеров в роутах.
- Упрощённый вариант переадресации в роутах.
- Событие «OnBeforeRouteProcess».
- Доработана функция jsonx.
- Функционал контейнера.
Файловые плагины
Возможно не все знают, но я уже решал эту задачу в своём дополнении Middlewares. В ZoomX я предлагаю доработанную версию файловых плагинов. Давайте познакомимся с ними.
Файловые плагины в отличие от файловых сниппетов представляют собой классы. Вот пример такого плагина.
<?php
// core/elements/plugins/MyPlugin.php
class MyPlugin extends \Zoomx\Elements\Plugin
{
// События и приоритеты.
public static $events = [
'OnMODXInit' => -101,
'OnHandleRequest' => 0,
];
public $disabled = false;
public function OnMODXInit($scriptProperties = [])
{
// ...
}
public function OnHandleRequest()
{
// ...
}
}Как видите, названия методов совпадают с названиями событий. Таким образом, один класс содержит функционал для разных событий в отличие от того же Laravel, где для каждого события создаётся отдельный класс. В свойстве $events указываются события, которые должны сработать. Это добавляет гибкости, так как можно запускать только указанные события. Также плагин можно отключить с помощью свойства $disabled.
Ещё хотелось бы отметить, что данный механизм легко подхватывает файловые элементы компонентов (если авторы их используют).
Модификатор markdown
Тут всё просто. Пригодится для тех, кто привык работать с этим форматом.
...
{'content'|resource|markdown}
...Механизм кэширования сниппетов
Сейчас MODX предлагает следующую логику кэширования — или сниппет никогда не кэшируется или кэшируется с сохранением результата на странице. Т.е. или он будет вызыватся при каждом запросе, или после первого выполнения он будет заменён на результат и больше работать не будет. Но этих вариантов бывает недостаточно. Приходилось писать сниппеты-обёртки, которые сохраняли результат на определённое время. Теперь это можно сделать прямо из коробки. В теге сниппета в атрибуте cache_lifetime нужно указать количество секунд для хранения результата в кэше.
{'name'|snippet:[...] cache_lifetime=3600 nocache}Короткие имена контроллеров в роутах
Если все контроллеры находятся в одном пространстве имён, то зачем постоянно их указывать. Теперь в системной настройке zoomx_controller_namespace можно указать неймспейс контроллеров, а в роутах писать только имя класса.
$router->get('uri', ['MyController', 'method']); // Преобразуется в Zoomx\Controllers\MyControllerУпрощённый вариант переадресации в роутах
Если для переадресации не нужны никакие проверки, то можно воспользоваться специальным методом redirect маршрутизатора.
$router->redirect('uri_from', 'uri_to');
// С указанием кода
$router->redirect('uri_from', 'uri_to', 301);Переадресовывать можно и роуты с масками. В URI переадресации нужно указать соответствующую переменную со знаком $ в фигурных скобках.
$router->redirect('articles/{id}', 'posts/{$id}');Событие «OnBeforeRouteProcess»
Данное событие сработает перед вызовом хандлера роута (контроллера или фукнции). В нем можно выполнить определённые проверки и изменить стандартное поведение. Например, можно взять из роута id объекта (ресурса, пользователя и т.д) и в плагине получить соответствущий объект. Таким образом в методе контроллера будет уже не id, а готовый объект.
Функция jsonx
За доработку этой функции можно поблагодарить @Николай Савин. Для удобства в эту функцию добавлен третий параметр для указания HTTP кода ответа.
$router->get('uri', function() {
// получение данных
...
return jsonx($array, $headers, 201); // Код ответа: 201 Created
});Если код статуса будет меньше 400, то свойство success, указывающее об успешности запроса, будет равно true.
{
success: true,
data: {
foo: "bar"
},
meta: {
total_time: "0.0123 s",
query_time: "0.0000 s",
php_time: "0.0123 s",
queries: 1,
memory: "2 048 kb"
}
}Для кода 400 и выше признак успешности будет false, а данные по ошибке будут в свойстве errors:
{
success: false,
data: {},
errors: {
foo: "bar" // данные из функции jsonx
},
meta: {
...
}
}А если включён обработчик ошибок ZoomX (по-умолчанию включён), то и все ошибки PHP и исключения будут также отдаваться в этом формате.
...
errors: {
"code": 500,
"title": "Error 500: Internal Server Error",
"message": "Сообщение об ошибке"
},
...Функционал контейнера
Ещё в главный сервис была добавлена возможность сохранять данные для последующего использования. Это часть функционала DI контейнера. Это промежуточная ступень к внедрению полноценного DI контейнера если появится потребность.
Сохранить в контейнер
zoomx()->set('foo', $object);
// или так
zoomx(['foo' => $object]);Затем в любом месте приложения можно получить сохранённую переменную.
$object = zoomx('foo');Заключение
Я опустил все технические подробности. Кому они интересны прошу сюда.
В общем, пробуйте, пишите чего не хватает, что доработать. У меня самого ещё много планов на этот компонент. И по функционалу и серию уроков снять. Надеюсь, в следующем году их все реализовать. Всех с Наступающим!
Комментарии: 35
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Я вот просто читая это уже мысленно погружаюсь в свой любимый slim, fastRoute, PHP-DI, middlewares
С наступающим.
Не воспринимайте как критику. Просто мысли вслух. Автору дополнения — искреннее уважение.
ZoomX — штука, безусловно, интересная :)
Но, на мой взгляд, уводит MODx от концепции более-менее простой и универсальной CMF к сложному «недофреймворку». Вместо того, чтобы менять сам MODx и делать его более быстрым, удобным и понятным большинству, я вижу тенденцию к уходу в доработку надстройками. Такие надстройки (так как их делают программисты для себя и других программистов) делают MODx более сложным.
Уникальность MODx как раз в простой и удобной админке, в простом создании ресурсов, отображении их в виде понятного дерева с понятным редактированием этих ресурсов из админки. Доступ к шаблону из самого ресурса. Система сама заботится о создании ссылок, их формировании и т.д. Простые дополнения, позволяют вывести меню, ресурсы, добавить форму, создать простой магазин и проч. Все это просто понять и применять новичкам.
С приходом таких дополнений, как ZoomX, нужно прописывать роуты, а создание ресурса превращается в написание кода. Это вряд ли привлечёт большое количество новичков в MODx (именно эта категория пользователей даёт популярность таким проектам, как Wordpress).
Если же есть задача привлечения опытных программистов — всё ещё не понятно, зачем пользоваться этим в связке с MODx, а не Laravel, Flask и другими адекватными «тру» фреймворками, в которых всё для опытного разработчика уже есть из коробки.
В любом случае — автор молодец, что посвящает этому время.
То что я вижу в примерах выше, очень похоже на то, как пишется сегодня какой-нибудь REST API. Но в MODx это почти нахер никому не нужно. Если у тебя будет средне или высоко бюджетный проект на котором потребуется хороший бек, ты уж точно не выберешь MODx с ZoomX или Fenom и пойдешь писать свой бек на каком-либо фреймворке.
Так что, ZoomX это заранее мертворожденный продукт, которым кмк будут пользоваться единицы. Все задачи для создания низкобюджетных сайтов на MODx — покрывает pdoTools с феномом.
P.S.
Собственно, наблюдая за тем как развивается MODx, у меня складывается впечатление что очень многое из того над чем сейчас работают люди, это либо мало кому будет нужно, либо уже совсем неактуально в свете последних тенденций рынка web-разработки.
Есть несколько «сложных проектов» (структурно и функционально) собранных без написания сниппетов и без знания программирования. Использовали только готовые компоненты из modstore.
В остальном — полностью согласен.
Сергей попытался внести в MODx чуть-чуть современного подхода к бекенду, но большинству сайтоделов на MODx оно нахер не всралось. В чем я не прав-то? Я уже молчу про то, что на рынке эти инструменты которые создаются для MODx не востребованы, как и сам MODx.
Когда ты последний раз писал апи? Обычный роутинг обычного проекта, при чем тут апи вообще?
а, ну расскажешь
Если у меня средне-высоко бюджетный проект где нужно накидать сайтец для корпоратов я пойду брать фреймворк? Да?
Проблема MODX в том, что разработчики в нем не растут. Вам дали инструмент который вам позволяет рости. Будут пользоваться те, кто хочет развиваться, единицы или нет — вопрос другой.
Очень похожи на
В каком-нибудь Express.
То ты очень классно обул клиентов-лохов. Самое сложное в сайтецах для корпоративов — это верстка. Все остальное набрасывается на условном WP или MODx за пару-тройку дней не особо утруждающей работы. Такие сайты живут недолго, нафига им самописная платформа? Нафига им вообще бек? Статику выплевываешь с небольшой логикой обработки каких-нибудь форм.
Конечно не растут, потому что сам MODx в стагнации уже много лет и единственные кто его до сих пор держат на плаву, это единицы разработчиков платных дополнений и сам стерк, у которых бизнес на нем завязан.
Ты сам знаешь думаю, в IT стоит перестать интересоваться новым на пару лет, как ты уже начинаешь выплывать из сферы.
В остальном хз как на такие высеры отвечать. Не буду ничего писать про легендарную тройку. Посмотри сколько скачиваний у ZoomX, а это уже версия 3.4. Так что, мне рассказывать то не особо будет нужно. Сам увидишь по востребованности.
P.S.
Людям дали инструмент. Но любой человек который перешагнул по навыкам и знаниям MODx, уйдет в более современный и востребованный на рынке инструмент. Вон тут уже упомянули Laravel.
Тут лишь остается рассматреть вариант сборки сайтов на MODx в кач-ве фриланса. Вариант конечно имеет место быть, но крайне спорный… Лучше уж взять хороший фриланс заказ и создавать его на микросервисной архитектуре, используя современные инструменты.
Мои клиенты нынче это тир1 финтех компании чей капитал больше бюджета твоего города. Лохи? Может быть, я так не считаю.
Кто ж спорит с этим? Как это влияет вообще на бэк сайта?
То есть по твоей логике в современных ресурсах нет никаких работ над сайтом? Ну то есть вообще никаких?
Гугл, допустим, любит живые сайты, где повышается ссылочная масса. Если мне инструмент позволяет писать «по современному» используя инструмент с прекрасной админкой и прочими вещами — то я тоже лох или как? Мне нужно было цеплять взрослый фреймворк чтобы гит использовать?
Проблема тройки — овощи у которых на гитхабе права на репозиторий, при чем тут вообще сторонние инструменты?
Окей, допустим я представил как твои мега-богатые клиенты, заказывают корпоративные сайты с очень динамичной, но люто багованной и что самое важное тяжелой и неудобной админкой.
Но представить что эти же клиенты получают на выходе проект, который не запускается в dev и stagging режимах. Над которым невероятно сложно работать в команде и который крайне сложно передать другим разработчикам на хотя бы лет 5 стабильной работы/доработки без рефакторинга. И уж тем более не версионируется… Нуу… Не, не могу представить. Хотя нет, вру, могу — если клиенты лохи.
Не буду разворачивать про тройку дискус, время покажет насколько эта штука нужна миру.
P.S.
И все таки я не понимаю в чем был не прав… В том что ZoomX будут пользоваться единицы или в том, что это шаблонизатор или про выбор MODx как инструмента для создания сайтов?
Субъективно более чем
Вот тут ты хорошую тему затронул. Я для этого использовал контексты, типа есть dev и прод и всем весело было. Надеюсь.
Очень удобно, когда у тебя сайт на 2-3-4 языках которые сделаны на контекстах. Это костыли, а не полноценная разработка на локальной машине с последующим тестированием на каком-нибудь сервере.
со вторым не сталкивался, не могу сказать из того что я бы мог придумать если бы мне такое пришло.
Всем вроде как понравилась наша работа и наличие багов никто не опровергал. Коллега с которым этим занимался даже вроде ишусы создал в репе модкса, но никто не захотел заниматься проблемой и рефакторить систему пермишенов, ни в 2х, ни в 3х.
Так что, нас уже кормили этими спасибами, больше не хочется.
P.S.
Нашел ишусы — github.com/modxcms/revolution/issues?q=%5Bbug%5D+Access+Policy+is%3Aopen. От Руслана Алеева. Файлик с данными пока найти не могу.
Да, и ещё, совет заказчикам — когда разработчик начинает нытьё о глюках дерева при большом количестве ресурсов, задумайтесь о его проф. пригодности.
Конечно я не буду тратить время на сбор списка причин, почему UI/UX админки в MODx плохой. Моя работа с Русланом уже 2 год лежит в репозитории MODx и никому не нужна. Как не нужен и твой шаблонизатор, как не нужен будет и мой список правок админки, как и не нужен будет MODx 3, в лучше случае, за исключением пары-десятков фрилансеров. Просто мой выбор, время которое у меня есть, потратить на что-то более интересное и ценное для меня. Твой выбор, это разрабатывать опенсурс компоненты для MODx. Я например люблю дискуссии и не только свои. В них можно найти намного больше, чем кажется людям думающим, что это только флуд и холивар.
P.S.
Забавно конечно когда ты находишь куча багов в таком фундаментальном для MODx ресурсе как ACL, пишешь об этом сообществу. Казалось бы, нужно решать проблему, но нет, все эти баги тащат в «новенькую» тройку. Просто, отлично.
Дискуссия. Много полезной пищи. Ещё больше её в комментариях про клиентов-лохов.
Вишенка на торте — «Баллада о железном слове» (мы в молодости называли это вагина-мяч) в двух актах.
Акт 1.
Акт 2.
Занавес.
П.С. Всё сказанное про медленное развитие MODX верно. И про PR, висящие годами. Многие из нас уже мозоль на языке натерли говоря об этом. И я в первых рядах. Но на сайте сообщества MODX рассказывать про то, что сайты нужно собирать на микросервисной архитектуре, это уж как-то… Для таких новаторов нужно особые ресурсы создавать.
П.П.С. Всё вышесказанное Павлу прошу читать вежливо и с уважением, ибо мы знаем друг друга давно и просто спорим. )
Что касается дискусии, то я считаю что лучше написать то — что написал я, чем хлопая в ладошки со слюной у рта писать фразы типа «Сергей, крутой компонент! Пиши исчо!». Да, я не написал ничего нового, ты наверное и так все это знал. Но для других, это будет именно пища, причем не факт что эти люди поддержат мою точку зрения.
— Я написал что могу, но я ведь не говорил что «зуб даю сейчас набросаю список». А то получается, что я кому-то что-то должен, не сделал этого и теперь пацанчики на районе прозвали меня пустословом. Да пожалуйста, мне не жалко.
— Несколько недель назад я хотел написать цикл статеек о том, как я от MODx пришел к разработке API на Nest. Почему так получилось, чем меня не устроил MODx, что такое Nest и почему именно нода и т.д. Одна из фундаментальных тем статей, это даже не про мой путь, а про то, почему при наличии крутых и современных фреймворков, на их базе не появляется новых WP, MODx и т.д. В качестве примера можно взглянуть на октябрь, который позиционирует себя как CMS, но при этом значительно сложней чем MODx, дак еще и платный. Кмк это максимально интересные статьи были бы.
Зачем они здесь? Ну конечно, здесь нужно писать статьи о том как экстендить extjs или кинуть очередной готовый пример какого-нибудь сниппета, плагина или модификатора… Для разработчиков мой самый любимый раздел, еще со времен когда в нем Вася объяснял внутрянку MODx или когда он начал писать статьи на тему Nuxt.js, тоже было очень интересно читать.
MODx уже разжеван и пережеван за эти годы много раз. Смысл выжимать воду из сухой тряпки? Пока что написание статей отложил, т.к. весь последний год работал на износе и времени на статьи просто не было… Надеюсь в этом году здесь или на своем сайте начну их писать.
Но я вполне допускаю что не прав и что людям тут нахер не сдались ни микросервисы, ни мои статьи уж тем более. Именно по этой причине я и рассматриваю написание статей на своем ресурсе.
P.S.
Очевидно что MODx это CMS и у него просто нету тех возможностей, которые есть у тех же фреймворков. Сравнивать их — не имеет смысла. Но когда мне люди пишут что они делают большие и дорогие проекты на MODx, мне очень интересно, а как они решают фундаментальные задачи разработки и те проблемы, которые у них появляется когда они выбирают MODx.
Правильно ты пишешь про программистов. А для них как раз ничего сложного нет. Это дополнительный инструмент для работы, а не обязательная замена. Раньше, чтобы так кодить, нужно было уходить во фреймворки. Сейчас также можно работать и в MODX до какого-то момента. Разве это плохо?
Закреплю посыл — ZoomX не для массового использования. И, кстати, изначальная задумка была для замены MODX шаблонизатора. Идея навеянна Evolution CMS. Но ребята ядро переписали под Laravel. С MODX это невозможно. Поэтому и дополнение. А потом решение стало обрастать правилами фреймворков. Именно поэтому мажорные версии. Но при этом концепция CMS никуда не делась и новичкам ничего не нужно заново учить. Т.е. ZoomX позволяет как бы растянуть момент покидания MODX.
ZoomX ничего этого не меняет. Он меняет только правила шаблонизации. Один проход. Как это принято не только во фреймворках, но и в других CMS. Подход MODX с многократной обработкой регулярными выражениями себя (в наше время) не оправдывает. А PHP шаблонизаторы компилируют код, оптимизируют его за счёт Opcache. Это даёт и гибкость и скорость.
Задача ZoomX не привлечь новичков, а удержать старых разработчиков. А если бы ты попробовал его или хотя бы прочитал доку, то не писал бы такое. )
Т.е. я его подключаю, переношу папку Templates в корневую директория ядра и прописываю новый путь с настройках компонента.
Затем раскомменчиваю дефелтный роут, ведущий на Главную страницу (так же как ина любую другую — результат тот же). После этого на новой установке срабатывает подмена шаблона MODX на ZoomX.
Но почему-то на действующих сайтах компонент не срабатывает. Настройки в принципе те же.