Мы будем разбирать создание именно «дополнения», а не «пакета» или «компонента». Для понимания разницы приведу в пример работу со сниппетами в MODX. Мы можем нажать в админке кнопку «Новый сниппет», ввести в открывшейся форме имя Hodor и код:
<?php return 'Hodor!';После сохранения мы можем вызывать его в любом месте шаблона и пользоваться сниппетом. Но если мы хотим использовать этот сниппет на нескольких сайтах, можно сделать транспортный пакет, который будет содержать в себе сниппет Hodor.
При разработке дополнений так же сначала нужно понять, как дополнения работают и из чего состоят. И только потом можно задумываться над тем, как же «запаковать» дополнение в транспортный пакет.
Если вы хотите разобраться, что такое «дополнение», как дополнения работают и что сделать, чтобы создать своё дополнение, настоятельно советую создать тестовый сайт на хостинге modhost.pro и повторять все действия, описанные в статье. Сложно будет понять весь механизм, не пройдя «ручками» по всем этапам.
Создадим в корне сайта папку things — это будет папкой нашего дополнения. А чтобы MODX знал, что эта папка вообще существует, создадим «Пространство имён» (в выпадающем списке внутри шестерёнки ilyaut.ru/cloud/1WpAB1.png)
- Имя things
- Путь к ядру {base_path}things/
Адреса дополнений MODX выглядят так: /manager/?a={controller}&namespace={namespace}
Мы создали пространство имён things — это namspace. Ну а контроллер можно назвать как угодно. Давайте назовём index — так же, как принято в HTML для главных страниц. Открываем в браузере страницу
/manager/?a=index&namespace=things
Понятное дело, что появилась ошибка — ведь папка у нас пустая. Создадим файл с тем именем, какое мы выбрали для контроллера. Если вы захотите, чтобы у вашего дополнения было несколько страниц, создавайте по одному файлу для каждой нужной страницы и придумывайте имена контроллеров (файлов). Для нашего контроллера имя файла будет таким: index.class.php.
Если MODX не даёт вам создать файл php, просто добавьте расширение php в системную настройку upload_files. Не забудьте по завершении работ удалить его из этого списка!
Когда пустой файл будет создан, страница нашего компонента отвалится с ошибкой 500. Скорее всего текст ошибки вы не увидите из-за настроек сервера. Если так и есть, то просто допишите в начало файла /manager/index.php такую строчку:
ini_set('display_errors', 1);
Теперь, если мы переведём текст ошибки с английского на русский, мы поймём, что
Класс 'ThingsIndexManagerController' не найден...
Дело в том, что в MODX приняты правила названий классов. Для файла контроллера название класса будет таким: {namespace}{controller}ManagerController. Запоминать это необязательно, всегда можно узнать требуемое название класса из текста ошибки.
Идём на поводу у MODX и описываем в нашем файле нужный класс:
<?php class ThingsIndexManagerController {}
После этого текст ошибки изменится — теперь MODX сообщает, что он пытается вызвать метод setProperties какого-то объекта, который не получен (on null). Пока непонятно. Смотрим код ошибки дальше.
Советую нажать Crtl+U, чтобы увидеть исходный код страницы — там текст ошибки будет разделён на строки. В строке с номером 0 есть имя нашего класса и имя метода getInstance. Вероятно, проблема в том, что у нас такого метода не существует. Давайте, его добавим. По названию метода можно предположить, что он должен «получать экземпляр» (не стесняйтесь пользоваться переводчиком). Экземпляр внутри класса — это $this. Значит, метод будет выглядеть так:
<?php class ThingsIndexManagerController { public function getInstance(){ return $this; } }
Смотрим, что теперь MODX хочет от нас. А хочет он метод setProperties, а у нас такого нет. Создадим его. У нас пока никаких свойств нет, они нам не нужны, поэтому метод не будет делать ничего.
public function setProperties() {}
Следующий требуемый метод — это initialize. Проведём тот же трюк:
public function initialize() {}
Новая ошибка и новый метод:
public function render() {}
Теперь ошибка уже непохожа на предыдущие. Остановимся и проанализируем последние действия. Мы добавили метод render. Это слово можно перевести как «отобразить». Давайте в коде укажем, что «отобразить» надо строку Hello world:
<?php class ThingsIndexManagerController { public function getInstance(){ return $this; } public function setProperties() {} public function initialize() {} public function render() { return 'Hello world'; } }
Отлично! Строка выведена на экран. Но нам надо, чтобы это была не просто HTML-страничка, а именно страница админки. Нам надо добавить в наш файл отображение верхнего меню, левой панели с деревом ресурсов и т. д. Это ж сколько работы! Но тут нам на помощь приходит MODX. В его ядре есть класс-заготовка modExtraManagerController (extra переводится как «дополнение»). В ООП такие классы-заготовки называются «абстрактными» — то есть сами они ничего не делают, а нужны только для того, чтобы мы в своих классах могли пользоваться заранее написанными методами.
Чтобы воспользоваться этой заготовкой и вывести все элементы админки, нужно наш класс унаследовать от класса modExtraManagerController. Пока удалим все наши методы — ведь они уже есть в заготовке:
<?php class ThingsIndexManagerController extends modExtraManagerController {}
Теперь по адресу нашей странички откроется полнофункциональная страница админки. Чтобы понять, какие возможности предоставляет нам заготовка, можно посмотреть в её код. Загляните, почитайте и переведите хотя бы названия методов: /core/model/modx/modmanagercontroller.class.php.
Меня, например, заинтересовал метод getPageTitle. Давайте, попробуем поменять title страницы нашего дополнения:
<?php class ThingsIndexManagerController extends modExtraManagerController { public function getPageTitle() { return 'Things'; } }
Кроме того, есть метод getTemplateFile. Ну что ж, давайте создадим файл-шаблон для нашего компонента. В папке things создадим файл home.tpl (если расширение tpl тоже запрещено, вы теперь знаете, что делать):
<h2>Things</h2>
И укажем путь к этому файлу в методе getTemplateFile:
<?php class ThingsIndexManagerController extends modExtraManagerController { public function getPageTitle() { return 'Things'; } public function getTemplateFile() { return dirname(__FILE__) . '/home.tpl'; } }
Прекрасно! Теперь код шаблона выводится в контентной части, заголовок страницы изменён на тот, который нужен нам. Осталось только добавить в верхнее меню ссылку на страницу нашего компонента.
Заходим в раздел «Меню» и создаём пункт в нужном месте (например, внутри пункта «Приложения»):
И вот, у нас готово наше собственное дополнение
На странице дополнения вы можете подключить, например, jQuery и Bootstrap и вывести пользователю какую-нибудь интерактивную информацию.
Но вообще, в MODX не принято баловаться сторонними фреймворками, так как в комплекте с MODX уже идёт замечательный фреймворк ExtJS, который заменяет сразу и jQuery, и Bootstrap.
В следующей статье мы приведём наше дополнение в стандартный для MODX вид с использованием ExtJS.
Это точно безопасно?
Вам не кажется, что все это как-то сложно, для простого создания расширения? Я использую другую CMS и там есть 5 типов аддонов, которые создаются одной командой в консоли, причем она сама определяет из названия, какой тип аддона необходимо создать.
Может вам лучше посмотреть на github?
github.com/piterden
Для обсуждения плюсов/минусов MODX есть другие статьи:
Я стараюсь в таких обсуждениях не участвовать, потому что ни разу не видел, чтобы кто-то кого-то убедил перейти с одной CMS на другую в комментариях в интернете.
На мой вопрос по-существу, вы не ответили!
Также, у меня нету желания, обсуждать плюсы и минусы Modx. Уверен — вам не выстоять в подобной полемике. Я лишь отметил очевидные диссонансы вашей статьи.
Однако, на Modx свет клином не сошелся. И я хочу чтобы другие разработчики были в курсе кое-каких ньюансов, о которых вы умалчиваете, например:
Вы знаете, мне пришлось потратить 2 года на ее поиски. Я почти стал экспертом в CMS, пока искал) Я бы не хотел, чтобы тот, кто тоже ищет как я, тратил столько же или больше времени. Тот, кто ее ищет — уже здесь задумается. Тот, кто не ищет — будет думать что я троль.
Илья, извините меня, пожалуйста. Ничего личного…
По поводу PyroCMS — это хорошо, что в ней нет некоторых минусов MODX. Но вы же не будете утверждать, что PyroCMS — идеал? Если вы уж против умалчивания, расскажите честно о минусах PyroCMS. Напишите, кому она не подойдёт, чтобы люди не теряли времени.
github.com/pyrocms/pyrocms/issues
Про Pyro — документация на английском. Ее мало. Мало готовых дополнений. Не нашел я живого сообщества, как по modx. И на биржах фриланса полно заказов по modx, но по pyro я тоже не нашел. Через пару лет — может быть…
Нет — сайт работал, я ничего не хочу сказать.
Modx не имеет очень важного — генераторов CRUD, без которых, дальше сайтов-визиток становится трудно и долго.
В Пиро высокий порог входа, и с доками вообще беда. Впрочем, с тестами тоже… Но зато там код категории A на codacy, что по сути — означает отсутствие необходимости в документации, ввиду комментированности и строгой структуры кода, а также, жесткой зависимости от названий.
В целом — это фреймворк для написания дополнений, реализованный, с применением многих принципов предметно-ориентированного проектирования, с использованием многих «модных» )) паттернов проектирования, а также, имеющий дополнительный абстрактный слой между пользователем и ORM (нормальным Eloquent ORM, а не как у modx — который даже union не делает). Этот слой, храня данные обо всей остальной структуре базы, в нескольких таблицах, динамически меняет структуру БД, проводя микро-миграции Laravel, по событиям Eloquent ORM (изменениям в данных сервисных таблиц слоя). То есть это виртуальный NoSQL на базе реляционной БД.
Про метакод и систему аддонов можно еще по стольку же рассказывать…
По поводу сообщества — вы, абсолютно не правы. Есть чат в слаке и форум. Бесплатный курс английского — это бонусная фича, только для тех, кто его не знает))
Вам лично, я могу оказать поддержку на русском (я могу материться — имейте ввиду) )))
Подводя итог, скажу, что я не позиционирую Пиро, как хорошее начало карьеры разработчика. Скорее, ЦА Пиро, это те разроботчики, которым становится уже маловато Modx, и которые вместе с этим, готовы развиваться.
Я, искренне убежден, что подход, предложенный мне этой ЦМС, близок к правильному.
PS Кстати, Twig — ничуть не сложнее и в разы функциональнее недошаблонизатора без-названия (это же беглое АПИ для смарти???), а Пиро пробрасывает весь Eloquent прямо в Twig. Вдумайтесь. Там union прямо в Twig работает.
Как вы отнесетесь к тому если сниму видео урок по вашему циклу уроков по созданию дополнения?