Templates

Templates in Maizzle typically contain the body of your email templates.

They're made up of two distinct sections:

  1. Front Matter
  2. Your HTML

Front Matter

Templates can define new variables and even override existing ones in your config through an optional YAML-style Front Matter block:

template.html
---
title: "Please confirm your email address"
---

Any Front Matter variables that you define in a Template are available under the page object, which means you can render them like this:

template.html
---
title: "Please confirm your email address"
---

<p>{{ page.title }}</p>

Extending Layouts

A Template can extend a Layout using the <extends> tag:

template.html
---
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.

How Extending Works

When a Template <extends> a Layout, a <block> tag with an identical name="" attribute is searched for in the Layout that is being extended.

Each matching tag 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 :

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 :

second.html
<extends src="src/templates/first.html">
  <block name="button">Child in second.html</block>
</extends>

After compilation, the body of second.html would be:

second.html
Parent
Child in second.html

Of course, if we use a template block in second.html, then we overwrite everything in first.html:

second.html
<extends src="src/templates/first.html">
  <block name="template">
    Second
    <block name="button">Child in second.html</block>
  </block>
</extends>

Result:

second.html
Second
Child in second.html

Multiple Extends

Multiple <extends> tags in a Template are not supported.

Only blocks from the last <extends> tag will be parsed.

src/templates/example.html
<extends src="src/layouts/header.html">
  <block name="template">
    stuff to put in header.html
  </block>
</extends>

<extends src="src/layouts/footer.html">
  <block name="template">
    stuff to put in footer.html
  </block>
</extends>

Result:

build_production/example.html
<block name="template">
  stuff to put in header.html
</block>

stuff to put in footer.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:

src/templates/promotional.html
<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:

example.html
<extends src="src/layouts/main.html">
  <block name="template">
    <table>
      <tr>
        <td>
          <p>...</p>
        </td>
      </tr>
    </table>
  </block>
</extends>

Expressions

Handlebars-like curly brace expression syntax is supported, allowing you to access variables from your Environment config or from the Template's Front Matter:

src/templates/example.html
<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 may use basic JavaScript expressions within curly braces:

src/templates/example.html
<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

Special characters are escaped when using two curly braces:

src/templates/example.html
---
markup: '<strong>Bold</strong>'
---

<extends src="src/layouts/main.html">
  <block name="template">
    {{ page.markup }}
    <!-- &lt;strong&gt;Bold&lt;strong&gt; -->
  </block>
</extends>

If you need to render values exactly as they are, use triple curly braces:

src/templates/example.html
---
markup: '<strong>Bold</strong>'
---

<extends src="src/layouts/main.html">
  <block name="template">
    {{{ page.markup }}}
    <!-- <strong>Bold</strong> -->
  </block>
</extends>

Ignoring expressions

Other templating engines, as well as many ESPs also use the {{ }} syntax.

If you want to prevent expression compilation and render the curly braces so you can evaluate them at a later stage, you have two options:

Ignore expressions inline

The Blade-inspired @{{ }} syntax is useful for one-offs, where you need to ignore a single expression. The compiled email will render {{ }} without the @.

src/templates/example.html
<extends src="src/layouts/main.html">
  <block name="template">
    @{{ page.markup }}
    <!-- {{ page.markup }} -->
  </block>
</extends>

Ignoring expressions inside Front Matter

You may use @{{ }} to prevent expressions in Front Matter from being evaluated.

src/templates/example.html
---
title: "Weekly newsletter no. @{{ edition_count }}"
---

<extends src="src/layouts/main.html">
  <block name="template">
    {{ page.title }}
  </block>
</extends>

Result:

build_production/example.html
Weekly newsletter no. {{ edition_count }}

If you're outputting the Front Matter variable in a custom tag like <if> or <switch>, you'll need to @-ignore it there as well.

src/layouts/main.html
<if condition="page.title">
-    <title>{{ page.title }}</title>
+    <title>@{{ page.title }}</title>
</if>

Ignore expressions using the <raw> tag

This is useful if you have a block with multiple lines containing {{ }} and want to ignore them all in one go:

src/templates/example.html
<raw>
  <p>The quick brown {{ animals[0] }} jumps over the lazy {{ animals[1] }}.</p>
</raw>

<raw> will be removed in the final output, but the curly braces will be left untouched:

build_production/example.html
<p>The quick brown {{ animals[0] }} jumps over the lazy {{ animals[1] }}.</p>

Expressions Options

Expressions may be configured in your project's config.js:

config.js
module.exports = {
  build: {
    posthtml: {
      expressions: {
        // posthtml-expressions options
      }
    }
  }
}

See all available expressions options.

Current template

Information about the Template file that is currently being processed is available under build.current in the config.

It's an object containing a parsed path of the destination file name, for example:

build: {
  current: {
    path: {
      root: '',
      dir: 'build_production',
      base: 'transactional.html',
      ext: '.html',
      name: 'transactional'
    }
  }
}

Can be used in Events like beforeRender if you need the current file name or extension.

Archiving

Maizzle will only compile templates found in path(s) that you have defined in build.templates.source, which have the same extension as the one defined in build.templates.filetypes (html by default).

If you create a lot of emails, your builds may start to slow down, since all templates are rebuilt every time you initially run the build <env> command or when developing locally and making changes to a Layout or Component.

You can archive Templates in two ways:

  1. 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).
  2. 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.
Copyright © 2022 Maizzle SRL Brand policy
Edit this page on GitHub