Добавляем свои переменные в шаблоны писем Joomla 5+
Шаблоны писем в Joomla. Вступление
С недавнего времени (с выходом Joomla 4) в CMS Joomla появился замечательный функционал — шаблоны писем. Эти шаблоны позволяют администратору настроить «под себя» все системные уведомления, которые отсылает CMS как пользователям, так и администраторам.
Шаблоны писем CMS Joomla
В предыдущих версиях Joomla, все это было реализовано через языковые переменные, что было крайне неудобно и максимально ограничивало администратора в «творческом полёте», именно администратора или контент менеджера, которые ни чего не понимают в разработке и им было практически невозможно поменять дизайн писем без привлечения разработчика. Слава Богу, это в прошлом!
На данный момент (Joomla 5) функционал шаблонов писем значительно расширен (и это, конечно же, не предел). Теперь администратор из админ. панели может отредактировать в удобном HTML редакторе (TinyMCE) любое системное письмо, которое отправляет Joomla. Может добавить любой текст, изображения, файлы — это круто!
Так же CMS позволяет вставлять необходимые переменные в тело письма (имя пользователя, почту, имя сайта и т.д.) так, как нужно в конкретном случае. Поддерживается редактирование для разных языков, то есть предусмотрена полная мультиязычность, как и в остальном функционале Joomla.
Редактор и переменные
И все это предлагается «под капотом» Joomla и отлично работает!
Но, как это всегда бывает, стандартного функционала может не хватить для определенных задач. Именно об этом и пойдет речь в этой статье.
Не хватает переменных…
В каждом наборе переменных, любого шаблона письма, содержится необходимый минимум, который Joomla предлагает «из коробки».
Естественно, что для каждого конкретного случая этот набор должен быть скорректирован и доработан. СMS Joomla предоставляет нам такую возможность с помощью использования плагинов.
Ко мне обратился заказчик, с просьбой расширить список переменных в шаблонах, а, конкретно, добавить поля пользователей в шаблон письма об успешной активации пользователя. Далее я расскажу, как я это реализовал.
Спасибо, Бро!
Успешной реализации задачи очень помог Сергей Толкачев. В своем посте на Хабре он описал триггеры событий, которые позволяют добавить новые переменные к шаблонам писем.
И в целом, моя статья, это только расширенное описание поста Сергея. За что ему огромное спасибо!
Кстати, не забудем поблагодарить и заказчика расширения, который спонсировал все это производство, а так же дал согласие на публикацию решения в свободном доступе — это веб студия Креативные Бизнес Системы.
Триггеры для плагина
И так… Задача поставлена: добавить в шаблоны писем переменные, которые будут содержать значения полей пользователей.
Для решения нам нужно:
Вывести переменные, в нашем случае это поля пользователей, в шаблоны писем в панели администратора Joomla. Для этого в Joomla предусмотрен триггер
BeforeRenderingMailTemplateEvent
.Передать новые переменные в письмо администратору. Для этого предусмотрен триггер
onMailBeforeRendering
.
Давайте рассмотрим каждое событие отдельно.
onMailBeforeTagsRendering
Это событие поможет нам добавить переменные (шорт-коды) в шаблон письма в панели администратора.
Шорт-коды шаблона письма
В моем случае нужно добавить к стандартным переменным поля пользователя. В качестве шорт-кодов будем использовать имя (не заголовок) полей.
Поля пользователя
Для получения всех полей пользователей используем
use \Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
$user_fields = FieldsHelper::getFields('com_users.user', true);
Вся функция будет выглядеть так
public function onMailBeforeTagsRendering(Event $event): void
{
$template = $event->getArgument(1); //получаем весь объект
$tags = $template->params['tags']; //получаем стандартные шорт-коды
$user_fields = FieldsHelper::getFields('com_users.user', true); //получаем все поля пользователя
$newtags = [];
foreach($user_fields as $field) {
$newtags[] = $field->name; //формируем массив с полями по имени поля
}
$tags = array_merge($tags, $newtags); //добавляем поля пользователя к стандартным шорт-кодам
$template->params['tags'] = $tags;// добавляем все в объект
}
Теперь в шаблонах писем, в переменных, у нас отображаются и шорт-коды полей пользователей.
Новые шорт-коды
Но этого еще не достаточно, нужно еще «заставить» Joomla понимать, какие данные отправлять, используя эти шорт-коды.
onMailBeforeRendering
Это событие позволит нам научить Joomla понимать новые шорт-коды и корректно отправлять данные по ним в письма.
Аргументом $event
для этой функции является экземпляр класса BeforeRenderingMailTemplateEvent
подключаем
use Joomla\CMS\Event\Mail\BeforeRenderingMailTemplateEvent;
У меня стояла задача, передать поля пользователей в письме администратору о необходимости активации нового пользователя, поэтому следующий код будет немного не стандартный, но очень хорошо подойдет для примера
public function onMailBeforeRendering(BeforeRenderingMailTemplateEvent $event): void
{
$templateId = $event->getTemplateId(); //id шаблона, как контекст
$app = Factory::getApplication();
if($templateId == 'com_users.registration.admin.verification_request') { //нужный мне шаблон письма
$activiti = $app->input->get('token', '', 'string');//получение токена (ключа активации), который содержится в ссылке на активацию
$db = Factory::getContainer()->get(DatabaseInterface::class); //подключаем базу
$db->setQuery("SELECT `id` FROM `#__users` WHERE `activation` = '{$activiti}'");
$user_id = $db->loadResult(); //получаем id пользователя, что бы передать его поля
} else {
$user = $app->getIdentity();
$user_id = $user->id;
}
$user_fields = FieldsHelper::getFields('com_users.user', ['id' => $user_id], true); //получаем все поля пользователя
$template = $event->getTemplate();//получаем весь объект письма
foreach($user_fields as $field) {
$data[$field->name] = $field->value; //получаем поля пользователя в нужном нам виде по имени поля
}
$template->addTemplateData($data);// передаем в объект новый массив шорт-кодов
}
Давайте подробно рассмотрим $data — массив, который передает данные о новых переменных (шорт-кодах).
$template = $event->getTemplate();//получаем весь объект письма
$data = [
'field_name' => 'field_vale',
];
$template->addTemplateData($data);// передаем в объект новый массив шорт-кодов
Теперь в шаблоне письма используем {field_name}
, чтобы в самом письме получить field_value
.
Всю логику разобрали. Далее соберем все в системный плагин, который позволит реализовать нужный функционал.
Системный плагин ShortMail
Структура плагина
- language
-- en-GB
--- plg_system_shortmail.ini
--- plg_system_shortmail.sys.ini
- services
-- provider.php
- src
-- Extension
--- Shortmail.php
- shortmail.xml
Файл манифеста shortmail.xml
plg_system_shortmail
Alexandr Novikov
2025-01-20
(C) 2025 Alexandr Novikov. All rights reserved.
GNU General Public License version 2 or later
support@joomlab.ru
https://joomlab.ru
1.0.0
joomLab\Plugin\System\Shortmail
services
src
language
en-GB/plg_system_shortmail.ini
en-GB/plg_system_shortmail.sys.ini
provider.php
set(
PluginInterface::class,
function (Container $container) {
$plugin = new Shortmail(
$container->get(DispatcherInterface::class),
(array) PluginHelper::getPlugin('system', 'shortmail')
);
$plugin->setApplication(Factory::getApplication());
return $plugin;
}
);
}
}
shortmail.php
'onMailBeforeRendering',
'onMailBeforeTagsRendering' => 'onMailBeforeTagsRendering'
];
}
public function onMailBeforeRendering(BeforeRenderingMailTemplateEvent $event): void
{
$templateId = $event->getTemplateId();
$app = Factory::getApplication();
$activiti = '1';
if($templateId == 'com_users.registration.admin.verification_request') {
$activiti = $app->input->get('token', '', 'string');
$db = Factory::getContainer()->get(DatabaseInterface::class);
$db->setQuery("SELECT `id` FROM `#__users` WHERE `activation` = '{$activiti}'");
$user_id = $db->loadResult();
} else {
$user = $app->getIdentity();
$user_id = $user->id;
}
$user_fields = FieldsHelper::getFields('com_users.user', ['id' => $user_id], true);
$template = $event->getTemplate();
foreach($user_fields as $field) {
$data[$field->name] = $field->value;
}
$template->addTemplateData($data);
}
public function onMailBeforeTagsRendering(Event $event): void
{
$template = $event->getArgument(1);
$tags = $template->params['tags'];
$user_fields = FieldsHelper::getFields('com_users.user', true);
$newtags = [];
foreach($user_fields as $field) {
$newtags[] = $field->name;
}
$tags = array_merge($tags, $newtags);
$template->params['tags'] = $tags;
}
}
Контекст
Чуть не забыл про контекст. Структура шаблонов писем отличается от общей структуры CMS, где, помимо триггеров, в основном используется еще и $context
для вывода плагина в нужном месте компонента.
В шаблонах писем вместо контекста используется template_id
$templateId = $event->getTemplateId();
//com_users.registration.admin.verification_request
template_id
Используя $template_id вы сможете добавить в разные шаблоны писем свои наборы полей.
Заключение
С помощью этого плагина вы сможете добавить в шаблоны писем поля пользователя. А на примере этого плагина вы сможете добавить в свои шаблоны писем абсолютно любые переменные (шорт-коды), при чем в разных шаблонах они могут быть разные!
Удачи!