Layouts

Layouts are the foundation of any email template in Maizzle.

Besides the standard parent-child templating relation, you can use Layouts to define markup that doesn't need to change often, like doctype, and <head> or <body> tags, with all the necessary child tags, like <meta>.

Creating Layouts

Layouts are typically stored in the src/layouts directory. Create a layout.html file with the required tags to yield the CSS and the Template body:

src/layouts/main.html
<!doctype html>
<html>
<head>
  <style>{{{ page.css }}}</style>
</head>
<body>
  <block name="template"></block>
</body>

You can use this as a Layout that your Templates extend.

Template Blocks

The Layout in the example above uses a <block> tag that acts like a 'marker'.

For each Template that extends this Layout, that marker is replaced with the contents of the Template's own <block name="template">.

Of course, you can use custom names for blocks, like <block name="content">.

Gotchas

Common pitfalls when using blocks.

Blocks don't work in Components

This won't work:

src/components/example.html
<block name="template">
  <content></content>
</block>

Extending from Components doesn't work

Blocks only work in a parent-child relationship, where the <block> in the child is added inside an <extends> tag.

One exception to this is inside Components, where something like this will not work:

src/components/example.html
<extends name="src/components/another-component.html">
  <block name="template">
    <content></content>
  </block>
</extends>

That will only render what was passed to the example.html Component, leaving the rest of the markup untouched:

src/templates/example.html
<component src="src/components/example.html">
  content passed to component
</component>

Result:

src/templates/example.html
<extends name="src/components/another-component.html">
  <block name="template">
    content passed to component
  </block>
</extends>

Block tags are not self-closing

<block> tags must always be closed:

src/layouts/main.html
<block name="template"></block>

If you write them as <block name="template" />, everything after the tag will be ignored.

Variables

Variables from your Environment config or from the Template's own Front Matter are available in a Layout under the page object.

You can use curly braces to output variables:

<meta charset="{{ page.charset || 'utf8' }}">

As you can see, inside curly braces you can write basic JavaScript expressions. These will be evaluated and the result will be output in your HTML.

Compiled CSS

The compiled Tailwind CSS for the current Template is available under page.css :

<style>{{{ page.css }}}</style>

We use 3 curly braces so that we output the CSS without escaping it - this is required for quoted property values, so that we don't get &quot; instead of " in CSS property values like url("") or in multi-word font names like in font-family: "Open Sans", sans-serif.

Environment

The Environment name is available under page.env. You can use it to output stuff based on the build command that you ran.

For example, we could use page.env to output some content only when running the maizzle build production command:

<if condition="page.env === 'production'">
  <p>This text will show when running `maizzle build production`</p>
</if>

Configuration

You may use the layouts key in config.js to customize the way you use Layouts:

config.js
module.exports = {
  build: {
    layouts: {
      // ... options
    }
  }
}

Let's take a look at the available options:

Encoding

You may specify the encoding used by your Layout files through the encoding option:

config.js
module.exports = {
  build: {
    layouts: {
      encoding: 'windows-1250',
    }
  }
}

By default, this is set to utf8.

Blocks

Normally, Template Blocks are defined through the <block> tag.

However, you may customize this tag name:

config.js
module.exports = {
  build: {
    layouts: {
      slotTagName: 'slot', // default: 'block'
      fillTagName: 'fill' // default: 'block'
    }
  }
}

Now you can use <slot> tags in the Layout, and <fill> tags in your Template:

src/layouts/main.html
<!doctype html>
<html>
<head>
  <style>{{{ page.css }}}</style>
</head>
<body>
  <slot name="template"></slot>
</body>
src/templates/example.html
---
title: "A template with a <fill> tag"
---

<extends src="src/layouts/main.html">
  <fill name="template"></fill>
</extends>

Root

You may define a path to the directory where your Layouts live:

config.js
module.exports = {
  build: {
    layouts: {
      root: 'src/layouts',
    }
  }
}

This allows you to specify a src="" relative to the path in that root key:

src/templates/example.html
<extends src="main.html">
  <block name="template">
    <!--  -->
  </block>
</extends>

Tag

You may use a tag name other than extends:

config.js
module.exports = {
  build: {
    layouts: {
      tagName: 'layout',
    }
  }
}
src/templates/example.html
<layout src="src/layouts/main.html">
  <block name="template">
    <!-- ... -->
  </block>
</layout>
Copyright © 2023 Maizzle SRL Brand policy
Edit this page on GitHub