Иногда дизайнеры рисуют непростые макеты. Внешне в них выглядит всё просто и красиво. Но ты смотришь на них и думаешь: "А с помощью чего я буду реализовывать это?".
Эта каруселька - плагином WT Content Image gallery. Эта карусель фото и видео в виде формата сторис - тоже им же. Вставляем просто шорткодами в материал.
Но между ними оказывается большой объём текста с описанием проекта, внутри которого ещё и блок с повторяемыми элементами - ассортимент проекта. Скрыт этот большой текст под спойлер с большой же синей кнопкой. Всё должно раскрываться / открываться, А заполнять всё это нужно далеко не программистам...
Размещать адаптивную вёрстку в материал - можно, но в данном случае не нужно. Кто-нибудь обязательно накосячит при копировании или правке шаблона текста. Поэтому решаем задачу с помощью пользовательских полей Joomla.
Вставить поля в материал Joomla можно с помощью кнопки редактора "Поле".

И в открывшемся модальном окне можно выбрать или конкретное поле или сразу группу полей.
Для содержимого спойлера мы создаем пользовательское поле типа редактор. В тело материала вставляем шорт код (с помощью кнопки редактора "поля") виде . Создаём собственный макет вывода для поля Joomla (писал об этом в Telegram-канале и в статье Как происходит рендер пользовательских полей в Joomla?). В нём оборачиваем содержимое в собственно спойлер. В моём случае это Bootstrap collapse.

Теперь любой текст, который мы наберём в поле редактора будет скрыт по умолчанию и будет раскрываться по нажатию на большую синюю кнопку. Содержимое поля пропускаем через HTMLHelper::_('content.prepare', $field->value);
, чтобы работали шорт-коды, если вдруг потребуются. Стало так:
<?php
// мы в файле своего макета поля
// /templates/[ВАШ_ШАБЛОН]/html/layouts/com_fields/field/etapy-raboty-nad-proektom.php
use Joomla\CMS\HTML\HTMLHelper;
// типичный код макета поля пропускаем
// тут куча вёрстки
// и самое важное - вывод содержимого поля.
// $value - это текст из поля редактора
echo HTMLHelper::_('content.prepare', $value);
Отображение пользовательского поля Joomla внутри другого пользовательского поля
Теперь принимаемся за адаптивную сетку с повторяемыми элементами - ассортимент проекта. Создаём 2 поля: типа text - для заголовка элемента, и textarea - для описания. Обоим полям ставим галочку "только в дочерней форме". Создаём 3-е поле - дочернюю форму, в настройках которой выбираем созданные заголовок и описание. Форма повторяемая, отключаем автоматическое отображение. Создаём свой макет вывода для поля и выбираем его в настройках.
Казалось бы - всё. Но нам нужно этот макет выводить ВНУТРИ предыдущего поля. Простая вставка шорт-кода типа в содержимое поля не заработала. Поэтому я решил напрямую вызвать метод
onContentPrepare
плагина Поля группы контент, убрав при этом обработку HTMLHelper
. Чтобы плагин заработал - нужно передать ему объект со свойством text
, в котором находится содержимое поля для обработки и свойство id
, означающее id материала Joomla. Не забыть указать нужный контекст для поля.
<?php
// мы находимся в файле макета поля
use Joomla\CMS\Factory;
$app = Factory::getApplication();
$fakeItem = new \stdClass();
// Получаем id текущего материала из объекта Input
$fakeItem->id = $app->getInput()->getInt('id');
// - это шорт код вставки поля с id 29 - "ассортимент проекта"
// к содержимому поля конкатенируем шорт-код для обработки
$fakeItem->text = $field->value . '';
// Получаем объект плагина
$joomlaFieldContentPlugn = $app->bootPLugin('fields', 'content');
// вызываем метод обработки напрямую
$joomlaFieldContentPlugn->onContentPrepare('com_content.article', $fakeItem, $app->getParams());
// выводим оба поля
echo $fakeItem->text;
Теперь всё работает.
Минусы такого подхода - хардкод. В случае, когда шорт-код поля виден в админке - проще понять что там нагорожено. Но в данном случае сайт веду я и никто кроме меня.
Почему не заработал content.prepare HTMLHelper?
Под капотом метод HTMLHelper::_('content.prepare', $text) делает в то же самое, что и сделал я: создаёт объект, эмулирующий объект материала, а потом возвращает обработанное свойство. За одним исключением - он не добавляет в него id
. А id
материала необходим контент-плагину Поля для того, чтобы получить значения полей конкретного материала. Поэтому, когда мы сами сделали то же самое, но добавив id - плагин заработал.