Задачи могут быть самые разные: поле аватара для пользователя в com_users
, дополнительный таб в форму редактирования материала, поле связи одной сущности с другой и т.д. Сразу оговорюсь, что бывает и «non-Joomla way» — то есть подходы, которые не предполагаются ядром CMS, но при этом и явно не запрещаются. Сейчас речь пойдёт о традиционном.
Наиболее употребимый вариант добавления своего поля или даже формы сводится к 2 простым вещам:
-
Создать XML файл с нужной формой
-
На событии
onContentPrepareForm
плагином добавить свою форму в форму расширения.
Приведу пример из одного давнего проекта — добавление поля с id
продаваемых курсов в Moodle в карточку товара компонента интернет-магазина RadicalMart Express.
XML файл с формой
Кто сильно заинтересуется — можно почитать официальную документацию Joomla How Forms Work. В XML мы описываем филдсеты и поля, а также с помощью структуры создаем имена для полей.
<?xml version="1.0" encoding="utf-8"?> <form> <fieldset name="wtradicalmartexpresstomoodle" label="PLG_WTRADICALMARTEXPRESSTOMOODLE_FIELDSET_LABEL" description="PLG_WTRADICALMARTEXPRESSTOMOODLE_FIELDSET_DESC"> <fields name="plugins"> <field addfieldprefix="Webtolk\JMoodle\Fields" type="moodleinfo" name="moodleinfo"/> <field addfieldprefix="Webtolk\JMoodle\Fields" type="courseslist" name="course_ids" multiple="true" layout="joomla.form.field.list-fancy-select" filter="intarray" label="PLG_WTRADICALMARTEXPRESSTOMOODLE_COURSE_ID" description="PLG_WTRADICALMARTEXPRESSTOMOODLE_COURSE_ID_DESC"/> </fields> </fieldset> </form>
Тег <fieldset>
— это отображаемый таб формы. У него есть системное имя name
, label
— название таба для людей. Description
— дополнительная информация в начале таба.
Вложенность в именах полей формы Joomla Form
В форме карточки товара RadicalMart Express для различной кастомной информации зарезервировано имя plugins
, куда, собственно говоря, плагины и могут помещать всякую нужную им информацию. Поэтому мы создаем секцию <fields name="plugins">
. а в ней уже помещаем описание нашего select
, который по REST API получает список доступных курсов из стоящего рядом Moodle. В HTML-коде имя поля будет jform[plugins][course_ids][]
. Если мы уберём секцию <fields>
, то имя поля было бы jform[course_ids][]
. Если нам нужно добавить уровень вложенности с именем level2
, то в XML файле формы мы добавляем ещё один <fields name="level2">
:
<?xml version="1.0" encoding="utf-8"?> <form> <fieldset name="wtradicalmartexpresstomoodle" label="PLG_WTRADICALMARTEXPRESSTOMOODLE_FIELDSET_LABEL" description="PLG_WTRADICALMARTEXPRESSTOMOODLE_FIELDSET_DESC"> <fields name="plugins"> <fields name="level2"> <field addfieldprefix="Webtolk\JMoodle\Fields" type="courseslist" name="course_ids" multiple="true" layout="joomla.form.field.list-fancy-select" filter="intarray" label="PLG_WTRADICALMARTEXPRESSTOMOODLE_COURSE_ID" description="PLG_WTRADICALMARTEXPRESSTOMOODLE_COURSE_ID_DESC"/> </fields> </fields> </fieldset> </form>
Дальше <field>
описывает поле, которое может быть как стандартным, так и пользовательским: из 3d-party компонента, библиотеки или ваше собственно из вашего же плагина. Достаточно указать namespace
этого поля. А имя поля = имени класса + «Field». В нашем примере это CourseslistField
.
Стандартные поля Joomla Form: официальная документация старая, официальная документация новая.
Добавление поля Joomla Form плагином
В примере кода ниже представлен не весь плагин Joomla целиком, но только один важный для нас метод — onContentPrepareForm
. Через это событие проходят все формы Joomla, поэтому нам важно проверять имя формы и добавлять свои поля только в нужную. Имя формы Joomla обычно строится по принципу com_component.entity
.
<?php use Joomla\CMS\Form\Form; use Joomla\Event\Event; public function onContentPrepareForm(Event $event): void { $form = $event->getArgument(0); $formName = $form->getName(); // Проверяем имя формы, чтобы не добавить таб в материалы или ещё куда-нибудь if ($formName === 'com_radicalmart_express.product') { Form::addFormPath(JPATH_SITE . '/plugins/system/wtradicalmartexpresstomoodle/src/Xmlform'); // fields - это имя файла в указанной папке - fields.xml $form->loadFile('fields', false); // грузим языковые константы для формы $lang = $this->getApplication()->getLanguage(); $extension = 'plg_system_wtradicalmartexpresstomoodle'; $base_dir = JPATH_ADMINISTRATOR; $reload = true; $lang->load($extension, $base_dir, $lang->getTag(), $reload); } }
Обработка данных формы
Если компонент предусматривает поля в базе для сторонних данных, то возможно вам ничего и не придется дописывать, а всю работу сделает за вас модель компонента. Если же ваши данные хранятся не в стандартной таблице базы данных компонента, а в своей, то в плагине нужно использовать событие onContentPrepareData
, то есть ДО onContentPrepareForm
. В нём вы делаете запрос в свою таблицу и оперируете данными. Это событие вызывается ДО подготовки формы. То есть Joomla сначала собирает все данные, потом собирает форму, затем биндит данные в форму. Для сохранения данных в свою таблицу можно использовать события onContentBeforeSave
или onContentAfterSave
. Также у компонентов могут быть свои собственные события для плагинов, вызываемые в процессе работы компонента.
Ну и всё… Теперь чтобы добавить ещё одно поле в карточку товара нам достаточно описать поле в XML-форме.
В хабе Joomla публиковал немало уже статей о разных видах плагинов. В них можно подчерпнуть информацию о структуре плагинов, логике и практике использования.
Полезные ресурсы
Ресурсы сообщества:
Telegram:
ссылка на оригинал статьи https://habr.com/ru/articles/853196/
Добавить комментарий