Как добавить свой повторяемый элемент интерфейса в класс HTMLHelper Joomla 4+
В API Joomla есть полезный инструмент - класс HTMLHelper. Он выводит HTML-элементы интерфейса с нужными параметрами: модальные окна, аккордеоны, табы, изображения и т.д. Для рендера мы передаём все нужные данные: заголовки окон, содержимое табов, атрибуты изображений. Плюс использования HTMLHelper в Joomla - это его универсальность, оторванность от контекста, а это значит, что его можно использовать везде. А также возможность использования логики при рендере в зависимости от вводных данных.
Ранее писал о том как:
- использовать HTMLHelper для рендера ссылок, изображений (источник)
- использовать HTMLHelper::image() для рендера изображений - подробнее (источник 1, источник 2)
- Совет о Joomla: использование FileLayout для рендера элементов макета. (источник)
- Layouts и subLayouts в Joomla (источник 1, источник 2)
Но это был обзор возможностей стандартных классов HTMLHelper. А что если нам нужно создать свой?
Создание собственного класса HTMLHelper в Joomla 4 / Joomla 5
Прежде всего посмотрим на то, как оно работает в Joomla 4+. Типичный вывод с помощью HTMLHelper выглядит так:
Нас интересует 2-й вариант - метод HTMLHelper::_(). Ссылки на метод: \Joomla\CMS\HTML\HTMLHelper::_(), файл libraries/src/HTML/HTMLHelper.php . Это метод-загрузчик классов.
Аргументы метода HTMLHelper::_()
$key - имя ресурса в реестре классов для HTMLHelper, которое выглядит следующим образом: (prefix).(class).function. Prefix - это неймспейс класса, если нужен. Class - собственно имя файла и класса по PSR-4. Prefix и Class являются опциональными. Главное, чтобы имя ресурса было уникальным. Function - имя метода в классе. Так, пример с HTMLHelper::_('bootstrap.renderModal') будет искать в реестре ресурс с именем bootstrap и найдет его.
И в классе \Joomla\CMS\HTML\Helpers\Bootstrap будет вызывать метод renderModal, куда и будут переданы дальнейшие аргументы метода HTMLHelper::_().
Создаём свой класс
Таким образом наша задача сводится к тому, чтобы написать класс с методами для рендера HTML нужных элементов интерфейса и с помощью системного плагина подключить его в реестр ресурсов HTMLHelper. В методах нашего класса HTMLHelper мы будем использовать стандартный механизм Joomla Layouts.
Почитать: Создание плагинов с учётом новой структуры Joomla 4. Также в хабе Joomla на Хабре есть ещё ряд статей, рассказывающих о создании различных типов плагинов.
Системный плагин
Если мы работаем с Joomla 4+, то нам подойдёт событие onAfterRoute(). В Joomla 5 появилось событие onAfterInitialiseDocument(), которое было создано специально для подобных случаев. Используем метод HTMLHelper::getServiceRegistry() для добавления своего класса в реестр классов Joomla HTMLHelper.
Пользовательский класс HTMLHelper в плагине
В нашем плагине в папке src создадим папку HTML, в которой будет лежать класс, например, Webtolk.
Код пользовательского класса HTMLHelper будет выглядеть следующим образом:
Таких методов в классе может быть несколько и каждый из них будет оперировать своими входными данными и возвращать свои макеты.
Отличительная особенность классов HTMLHelper состоит в том, что в них можно реализовывать логику, которая напрямую влияет на отображение. Это могут быть дочерние элементы, значения по умолчанию, подключение необходимых Web Assets и так далее. Таким образом логика остаётся в классах, а вёрстка остаётся в макетах (layouts).
Файл макета вывода пользовательского класса HTMLHelper
Осталось создать макет вывода, где собственно будет находиться вёрстка. Мы реализуем его с помощью стандартного для Joomla механизма Layouts (Layouts и subLayouts в Joomla). В Joomla есть понятие layout. Это кусочек вёрстки, который можно многажды использовать в любом месте сайта: как в панели администратора, так и во фронтенде. Можно рассматривать лейауты как оторванные от контекста элементы дизайна. Находятся они в папке layouts в корне сайта. Как их использовать? Один из вариантов - использование LayoutHelper.
1-й аргумент - это dot-separated (разделенный точками) путь к файлу лейаута. Название папки "layouts" в данном случае пропускается как само собой разумеющееся. Внутрь файла приходит массив $displayData, в котором будут лежать наши данные - $key - $displayData['key']. Но в нашем плагине мы сказали LayoutHelper искать макет не только по стандартным путям (в папке layouts от корня), но и в папке плагина:
3-й аргумент LayoutHelper::render() - $basePath - это путь, относительно которого будет применяться dot-separated путь, последняя часть которого - имя файла без расширения.
Само содержимое файла /plugins/system/myplugin/layouts/indicator/green.php примитивно:
Результат
Теперь абсолютно везде в Joomla мы можем использовать простой рендер нужного элемента интерфейса одной строчкой:
Заключение
В заключение хочу сказать спасибо Joomla-разработчику Виталию Некрасову, у которого я частично подглядел этот подход и это способствовало появлению данной статьи.
Полезные ресурсы
Ресурсы сообщества:
Telegram: