Templates
Templates in Maizzle contain the body of your email templates.
They're made up of two distinct sections:
- Front Matter
- Your HTML
Front Matter
Templates can define variables and even override existing ones in your config, through YAML-style Front Matter.
It looks like this:
---
title: "Please confirm your email address"
---
Front Matter variables are available under the page
object, which means you can render them in your Templates, like this:
<p>{{ page.title }}</p>
Extending Layouts
A Template can extend a Layout using the <extends>
tag:
---
preheader: The Weekly Newsletter
---
<extends src="src/layouts/main.html">
<!-- Add block tags here -->
</extends>
The path provided in the src=""
attribute must be relative to the path in build.layouts.root
from your config.
Template render error
How Extending Works
When a Template <extends>
a Layout, a <block>
tag with an identical name=""
attribute is searched for in the Layout being extended.
Each matching tag found in the Layout will be replaced with the contents of its corresponding <block>
tag from the Template.
Extending Templates
A Template can also extend another Template.
For example, imagine src/templates/first.html
:
<extends src="src/layouts/main.html">
<block name="template">
Parent
<block name="button">Child in first.html</block>
</block>
</extends>
We could then extend it in src/templates/second.html
:
<extends src="src/templates/first.html">
<block name="button">Child in second.html</block>
</extends>
The body of second.html
would be:
Parent
Child in second.html
Of course, if we use a template
block in second.html
, then we overwrite everything in first.html
:
<extends src="src/templates/first.html">
<block name="template">
Second
<block name="button">Child in second.html</block>
</block>
</extends>
Result:
Second
Child in second.html
Blocks
For a Layout to render a Template's body, that body must be wrapped in a <block>
that has the same name=""
attribute in both the Template and the Layout.
In the Starter, we named it template
:
<block name="template">
<!-- email body -->
</block>
Everything inside that <block>
will be output into the Layout that the Template extends, wherever a <block name="template"></block>
is found.
Multiple Blocks
Your Templates can use as many blocks as you need.
For example, the Starter uses a head
block in its main Layout, allowing you to inject additional code into the <head>
of you HTML email, right from the Template.
Basic Example
Here's a very basic Template example:
<extends src="src/layouts/main.html">
<block name="template">
<table>
<tr>
<td>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</td>
</tr>
</table>
</block>
</extends>
Expressions
Maizzle uses posthtml-expressions
, allowing you to access variables from your environment config or from the Template's Front Matter inside curly brace syntax:
<extends src="src/layouts/main.html">
<block name="template">
You ran the `maizzle build {{ page.env }}` command
</block>
</extends>
Running maizzle build production
would render this:
You ran the `maizzle build production` command
You can even use some JavaScript expressions within curly braces:
<extends src="src/layouts/main.html">
<block name="template">
doctype is {{ page.doctype || 'not set' }}
this email {{ page.env === 'production' ? "is" : "isn't" }} production ready!
</block>
</extends>
Unescaping variables
By default, special characters are escaped:
---
markup: '<strong>Bold</strong>'
---
<extends src="src/layouts/main.html">
<block name="template">
{{ page.markup }}
<!-- <strong>Bold<strong> -->
</block>
</extends>
If you need to render values exactly as they are, so that maybe markup is interpreted, use triple curly braces:
---
markup: '<strong>Bold</strong>'
---
<extends src="src/layouts/main.html">
<block name="template">
{{{ page.markup }}}
<!-- <strong>Bold</strong> -->
</block>
</extends>
Ignoring
Other templating engines, as well as many ESPs also use the {{ }}
syntax.
If you want to output the curly braces as they are, so you can evaluate them at a later stage, you have two options:
Use
@{{ }}
The Blade-inspired syntax is useful for one-offs, where you need to ignore a single expression. The compiled email will render
{{ }}
without the@
.Use the
<raw>
tagThis is useful if you have multiple lines containing
{{ }}
and want to ignore them all in one go:<raw> Nostrud laboris sunt Lorem {{ var1 }} cupidatat fugiat tempor ad tempor anim. Veniam non sit {{ var2 }} ipsum ad qui. </raw>
The
<raw>
tag will be removed in the final output, but the curly braces will be left untouched.
Ignoring expressions inside Front Matter
Due to the way Maizzle works to enable expressions inside Front Matter, if you need to ignore an expression there you will also have to ignore it in the Layout or Template where you are using it.
For example, in the Template's Front Matter:
---
title: "Weekly newsletter no. @{{ edition_count }}"
---
In the Layout:
<if condition="page.title">
<title>Weekly newsletter no. @{{ edition_count }}</title>
</if>
This is required because Maizzle first evaluates expressions in Front Matter and then it evaluates them again in the resulting HTML, meaning it will basically evaluate your expression twice.
Options
You can configure posthtml-expressions
in your config.js
:
module.exports = {
build: {
posthtml: {
expressions: {
// posthtml-expressions options
}
}
}
}
Besides configuring templating tag names, here you can also pass other options to the plugin. For example, you could change the default expression delimiters from {{ }}
to something like [[ ]]
:
module.exports = {
build: {
posthtml: {
expressions: {
delimiters: ['[[', ']]']
}
}
}
}
You'd now use variables or expressions like this:
<extends src="src/layouts/main.html">
<block name="template">
doctype is [[ page.doctype || 'not set' ]]
</block>
</extends>
See all posthtml-expressions
options.
Archiving
Maizzle will only compile templates found in path(s) you have defined in build.templates.source
, and which use the extension defined in build.templates.extensions
.
If you create a lot of emails, your builds can start to slow down, since all templates are rebuilt every time you run the build <env>
command or when developing locally and making changes to a Layout or Component.
You can archive Templates in two ways:
- Move them to a directory outside the one defined in
build.templates.source
, so they don't get copied over to the destination directory (recommended). - Change their file extension to something that is not defined in
build.templates.filetypes
. They'll just be copied over to the destination, Maizzle will not try to compile them.