Добавляем свои переменные в шаблоны писем Joomla 5+

от автора

Шаблоны писем в Joomla. Вступление

С недавнего времени (с выходом Joomla 4) в CMS Joomla появился замечательный функционал — шаблоны писем. Эти шаблоны позволяют администратору настроить «под себя» все системные уведомления, которые отсылает CMS как пользователям, так и администраторам.

Шаблоны писем CMS Joomla

Шаблоны писем CMS Joomla

В предыдущих версиях Joomla, все это было реализовано через языковые переменные, что было крайне неудобно и максимально ограничивало администратора в «творческом полёте», именно администратора или контент менеджера, которые ни чего не понимают в разработке и им было практически невозможно поменять дизайн писем без привлечения разработчика. Слава Богу, это в прошлом!

На данный момент (Joomla 5) функционал шаблонов писем значительно расширен (и это, конечно же, не предел). Теперь администратор из админ. панели может отредактировать в удобном HTML редакторе (TinyMCE) любое системное письмо, которое отправляет Joomla. Может добавить любой текст, изображения, файлы — это круто!

Так же CMS позволяет вставлять необходимые переменные в тело письма (имя пользователя, почту, имя сайта и т.д.) так, как нужно в конкретном случае. Поддерживается редактирование для разных языков, то есть предусмотрена полная мультиязычность, как и в остальном функционале Joomla.

Редактор и переменные

Редактор и переменные

И все это предлагается «под капотом» Joomla и отлично работает!

Но, как это всегда бывает, стандартного функционала может не хватить для определенных задач. Именно об этом и пойдет речь в этой статье.

Не хватает переменных…

В каждом наборе переменных, любого шаблона письма, содержится необходимый минимум, который Joomla предлагает «из коробки».

Естественно, что для каждого конкретного случая этот набор должен быть скорректирован и доработан. СMS Joomla предоставляет нам такую возможность с помощью использования плагинов.

Ко мне обратился заказчик, с просьбой расширить список переменных в шаблонах, а, конкретно, добавить поля пользователей в шаблон письма об успешной активации пользователя. Далее я расскажу, как я это реализовал.

Спасибо, Бро!

Успешной реализации задачи очень помог Сергей Толкачев. В своем посте на Хабре он описал триггеры событий, которые позволяют добавить новые переменные к шаблонам писем.

И в целом, моя статья, это только расширенное описание поста Сергея. За что ему огромное спасибо!

Кстати, не забудем поблагодарить и заказчика расширения, который спонсировал все это производство, а так же дал согласие на публикацию решения в свободном доступе — это веб студия Креативные Бизнес Системы.

Триггеры для плагина

И так… Задача поставлена: добавить в шаблоны писем переменные, которые будут содержать значения полей пользователей.

Для решения нам нужно:

  1. Вывести переменные, в нашем случае это поля пользователей, в шаблоны писем в панели администратора Joomla. Для этого в Joomla предусмотрен триггер BeforeRenderingMailTemplateEvent.

  2. Передать новые переменные в письмо администратору. Для этого предусмотрен триггер 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

<?xml version="1.0" encoding="utf-8"?> <extension type="plugin" group="system" method="upgrade">     <name>plg_system_shortmail</name>     <author>Alexandr Novikov</author>     <creationDate>2025-01-20</creationDate>     <copyright>(C) 2025 Alexandr Novikov. All rights reserved.</copyright>     <license>GNU General Public License version 2 or later</license>     <authorEmail>support@joomlab.ru</authorEmail>     <authorUrl>https://joomlab.ru</authorUrl>     <version>1.0.0</version>     <description><![CDATA[Дополнительные поля пользователей в шаблоне письма]]></description>     <namespace path="src">joomLab\Plugin\System\Shortmail</namespace>     <files>         <folder plugin="shortmail">services</folder>         <folder>src</folder>         <folder>language</folder>     </files>     <languages folder="language">         <language tag="en-GB">en-GB/plg_system_shortmail.ini</language>         <language tag="en-GB">en-GB/plg_system_shortmail.sys.ini</language>     </languages>     <config>         <fields name="params">             <fieldset name="basic">                 <!-- Add your plugin parameters here -->             </fieldset>         </fields>     </config> </extension>

provider.php

<?php /**  * @package     joomLab.Plugin  * @subpackage  System.Shortmail  *  * @copyright   (C) 2025 Alexandr Novikov. All rights reserved.  * @license     GNU General Public License version 2 or later; see LICENSE.txt  */  \defined('_JEXEC') or die;  use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use joomLab\Plugin\System\Shortmail\Extension\Shortmail;  return new class () implements ServiceProviderInterface {     public function register(Container $container): void     {         $container->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

<?php /**  * @package     joomLab.Plugin  * @subpackage  System.Shortmail  *  * @copyright   (C) 2025 Alexandr Novikov. All rights reserved.  * @license     GNU General Public License version 2 or later; see LICENSE.txt  */  namespace joomLab\Plugin\System\Shortmail\Extension;  defined('_JEXEC') or die;  use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Event\SubscriberInterface; use Joomla\Event\Event; use Joomla\CMS\Event\Mail\BeforeRenderingMailTemplateEvent; use Joomla\Database\DatabaseInterface; use \Joomla\Component\Fields\Administrator\Helper\FieldsHelper; use Joomla\CMS\Factory;  class Shortmail extends CMSPlugin implements SubscriberInterface {     protected $autoloadLanguage = true;      public static function getSubscribedEvents(): array     {         return [             'onMailBeforeRendering' => '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

Используя $template_id вы сможете добавить в разные шаблоны писем свои наборы полей.

Заключение

С помощью этого плагина вы сможете добавить в шаблоны писем поля пользователя. А на примере этого плагина вы сможете добавить в свои шаблоны писем абсолютно любые переменные (шорт-коды), при чем в разных шаблонах они могут быть разные!

Удачи!


ссылка на оригинал статьи https://habr.com/ru/articles/875868/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *