Joomla 4 introduced a new core component, Mail Templates
(com_mails
). You can access it from the System
dashboard.
This component allows you to manage email templates used by the different components which make use of Joomla's new Mail Templates feature. The user can choose to customise the plain text email's contents or even provide a full HTML email — or both. This is a much better user experience than language overrides, especially when it comes to HTML email.
Using this feature is recommended, but not required. If you decide to use it for your components there's a bit of trouble you need to get through.
Installing mail templates
Mail templates live in the database, in the #__mail_templates table. The fields for each mail template are as follows:
- template_id
-
The unique identifier of your mail template in the form
com_example.
wheresomething
com_example
is your component andsomething
is a key consisting of just lowercase alphanumeric characters and underscores (a-z, 0-9 and _). This is a hard requirement; language string keys will be created using the template_id. This ID is what you will use when you want to send emails with this email template. - language
-
The language tag of the mail template, e.g.
en-GB
for British English.Important The default mail template should have an empty string as its language to apply to all languages. This is very different from literally everything else in Joomla which uses a
*
as the catch-all language. - subject
-
The language string with the subject line of the email. The content of the language string can use variables (see params below).
- body
-
The language string with the body of the plain text version of the email. The content of the language string can use variables (see params below).
- htmlbody
-
The language string with the body of the HTML version of the email. The content of the language string can use variables (see params below).
- attachments
- extension
-
The name of your extension, e.g.
com_example
.Note You may wonder, if my template_id already contains this why is this a separate column? You are right, it doesn't make sense. Joomla could have just used an index on the template_id column with the same performance results or, if it was actually concerned about performance, use the numeric extension ID in this column. It doesn't make anysense; it is what it is.
- params
-
A JSON-serialised object with the parameters to the mail template. What is most important for us is its
tags
property. For example, you may have this params content:{ "tags": [ "FOO", "BAR", "BAZ" ] }
This tells Mail Templates that you can use the variables
{FOO}
,{BAR}
and{BAZ}
in the subject, body and HTML body of the mail templates — and let users know that in the user interface. When sending emails via the Mail Templates feature you will have to provide the values for these variables. The variable names MUST always consist of uppercase letters, dashes, underscores and colons.
Moreover, you will need to supply a few language strings in you
backend INI language file (e.g.
administrator/languages/en-GB/com_example.ini
).
You need to provide a language string whose key is the uppercase version of your extension name, e.g.
COM_EXAMPLE="Example component"
This is used in the Mail Templates drop-down for selecting a component to filter by.
For each email template you will need to provide a few “magic”
language strings on top of the language strings you
defined in the subject, body,
and htmlbody columns. Assuming a
template_id com_example.foo_bar
you will
need to provide the following language strings:
COM_EXAMPLE
_MAIL_FOO_BAR
_TITLE-
A long title for your email template, displayed in the user interface. The content of this language string should be something similar to “My Component Name: When This Mail Template Is Sent”.
COM_EXAMPLE
_MAIL_FOO_BAR
_SHORT-
A short title for your email template. I am not sure when this is used.
COM_EXAMPLE
_MAIL_FOO_BAR
_DESC-
A short description of your email template, displayed in the user interface.
Using mail templates
The Mail Templates feature does NOT send emails. It only provides you with a pre-configured Joomla Mailer object you will use to send emails with.
This is how you use it:
/** * @var string $templateId The template ID you want to use, e.g. com_example.foo_bar * @var string $langTag The language tag for your email, e.g. 'en-GB' */ $template = new \Joomla\CMS\Mail\MailTemplate($templateId, $langTag); // Add the contents of your variables here $template->addTemplateData([ 'FOO' => 'Contents of the {FOO} variable', 'BAR' => 'Contents of the {BAR} variable', 'BAZ' => 'Contents of the {BAZ} variable', ]); /** * @var string $emailAddress The email address of the recipient, e.g. jane@example.com * @var string $recipientName The full name of your recipient, e.g. "Jane Doe" */ $template->addRecipient($emailAddress, $recipientName); // Send the email $template->Send();
If you want to customise the Joomla Mailer object used by the
MailTemplate
class —for example to set custom
headers, add inline images or attachments which cannot be handled by
MailTemplate, etc— you can pass it as the third parameter to its
constructor, e.g.
$mailer = \Joomla\CMS\Factory::getMailer(); $mailer->addCustomHeader('X-Vanity-Header', 'Joomla! Rocks'); $template = new \Joomla\CMS\Mail\MailTemplate($templateId, $langTag, $mailer);
Do keep in mind that each email template may have its own
configuration about the sender address and sending method (e.g. SMTP
information). These settings will override the same settings in your
custom mailer object when you call Send()
.
![]() | Tip |
---|---|
The above will error out if MailTemplate cannot find a suitable template. You can check if a suitable template exists by doing this before any of the code above: $template = Joomla\CMS\Mail\MailTemplate::getTemplate($templateId, $langTag); If $template is empty do NOT go through MailTemplate. You can simply not send the email, provide an alternative, throw an error or otherwise handle this condition in a way appropriate for your application. |
Caveats
Users can, and will, mess up the Mail Templates. If they just mess up the subject, plain text body or HTML body they can recover easily by using the respective reset button in the user interface.
If they create a specific language version of a mail template they cannot remove it without messing with the database.
If you update a mail template, adding more tags (variables) in its parameters you will need to write update SQL which updates all entries with the relevant template_id BUT you should note that by overwriting the contents of the params column you will be resetting the user's preferences about the mailer itself (sender, sending method, credentials etc). Therefore updating mail templates actually requires writing PHP code in your extension's installation script to run on update, read all mail templates with the affected template_id, decode the params, update the tags and write everything back to the database. It's a big old pain in the posterior.
A final word of caution. The MailTemplate class has some static
methods such as createTemplate
and
updateTemplate
. Don't use
them. They will error out.