HowTo: Create Custom Email Templates in Magento 2


In the previous post I showed how to send an email programmatically, but I left one piece out on purpose, the template. Here is how I register a custom email template that ships with the module and can still be overridden by the merchant from the admin.

This post assumes that there is already a custom module created in app/code/Vendor/Module. If you need to know how to create a custom module, look at How to create a custom module for Magento 2.

Register the template

Templates that live in the code are declared in etc/email_templates.xml. The id is what we later pass to setTemplateIdentifier.

xml
<?xml version="1.0"?>
<!-- app/code/Vendor/Module/etc/email_templates.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Email:etc/email_templates.xsd">
    <template id="vendor_module_email_template"
              label="My Custom Email"
              file="custom_email.html"
              type="html"
              module="Vendor_Module"
              area="frontend"/>
</config>

The template file

The file referenced above goes in view/frontend/email/. It uses the same directive syntax as any Magento email, so you can pull in variables with {{var ...}} and reuse the standard header and footer.

html
<!-- app/code/Vendor/Module/view/frontend/email/custom_email.html -->
<!--@subject My Custom Email Subject @-->
{{template config_path="design/email/header_template"}}

<table>
    <tr>
        <td>
            <p>{{trans "Hi %name," name=$customer_name}}</p>
            <p>{{trans "Your order %id has been received and is now being processed." id=$order_id}}</p>
            <p>{{trans "Thanks for shopping with us."}}</p>
        </td>
    </tr>
</table>

{{template config_path="design/email/footer_template"}}
Notice: The @subject comment at the top sets the default subject line, and it also accepts variables, e.g. <!--@subject Your order {{var order_id}} @-->.

Making it editable from the admin

Because we declared it in email_templates.xml, the merchant can go to Marketing > Email Templates, click Add New Template, load our template from the Template dropdown and customise it without touching the code. When they save, Magento uses their version instead of the file one.

Run setup:upgrade, flush the cache, and the template is ready to be used by the sender service from the previous post.

Hope this helps.

If you have any question or know a better way to achieve this, feel free to share in the comments below.

Related links: