Skip to content

Component templates

This article explains how component templates work, step by step. For a quick list of all of EmailShepherd’s template syntax, see the template reference. For ready-made solutions, see template examples.

A component’s template is the HTML it outputs when an email is exported. Templates use Liquid, a templating language, to add the content people enter in the email editor. So each email can have its own content while the HTML stays the same.

To edit a template, open the component in Component Builder and click Code. See Edit a component’s template.

Every field has a Liquid variable. To output the field’s value, put its Liquid variable in double curly brackets.

For a text field with the Liquid variable headline:

<table>
<tr>
<td>
<h1>{{headline}}</h1>
</td>
</tr>
</table>

When the email is exported, {{headline}} is replaced with whatever was entered in the field, such as Gear up for autumn.

Each template can only use its own component’s fields, plus global fields. To find a field’s Liquid variable, look on the component’s Fields tab.

A filter changes a value before it’s output. Add it after the variable with a |.

For example, the upcase filter changes text to capitals:

<p>{{headline | upcase}}</p>
  • headline is the field’s Liquid variable.
  • | passes the value to a filter.
  • upcase is the filter.

So if the field contains Gear up for autumn, the output is GEAR UP FOR AUTUMN.

Some filters take a value of their own, written after a colon. For example, default outputs its value when the field is empty:

<a href="{{cta_url}}">{{cta_text | default: "Shop now"}}</a>

For every standard filter, see Liquid filters in the Liquid documentation. EmailShepherd adds a track_link filter for link tracking.

Show content only when a condition is true

Section titled “Show content only when a condition is true”

Use an if tag to output part of a template only when a condition is true. Tags are written in {% %} rather than double curly brackets, and don’t output anything themselves.

This component has a boolean field, show_cta, that turns its button on and off:

<table>
<tr>
<td>
<p>{{body_text}}</p>
{% if show_cta %}
<a href="{{cta_url}}">{{cta_text}}</a>
{% endif %}
</td>
</tr>
</table>
  • {% if show_cta %} starts the condition. The content after it is only output when show_cta is on.
  • {% endif %} ends it.

You can also compare values, for example with an enum field, and use {% else %} for what to output otherwise:

{% if button_style == "outline" %}
<a href="{{cta_url}}" style="border: 2px solid #1F6F5C; color: #1F6F5C;">{{cta_text}}</a>
{% else %}
<a href="{{cta_url}}" style="background-color: #1F6F5C; color: #ffffff;">{{cta_text}}</a>
{% endif %}

See control flow tags in the Liquid documentation for more.

Use a for tag to output something once for each item in a list.

This component has a text field, categories, where people enter a comma-separated list such as Tents, Boots, Jackets:

<table>
{% assign category_list = categories | split: "," %}
{% for category in category_list %}
<tr>
<td>{{category | strip}}</td>
</tr>
{% endfor %}
</table>
  • {% assign category_list = categories | split: "," %} splits the text at each comma and stores the list as category_list.
  • {% for category in category_list %} repeats the content up to {% endfor %} once for each item, with the item available as category.
  • {{category | strip}} outputs the item, with any spaces around it removed.

See iteration tags in the Liquid documentation for more.

Templates can also use details about the email being rendered, such as its subject line, and your design tokens. These are in the render_context object:

<title>{{render_context.email.content.subject}}</title>

See Render context for everything it contains.

Every Email Design System has one container component. It’s the outer shell of every email: the <html>, <head> and <body> tags, your CSS, and the area people drop the other components into. It’s always at the top of the left panel in Component Builder.

The container’s template must include {{children}}, which marks where the email’s components go. A basic container template looks like this:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
<meta name="x-apple-disable-message-reformatting">
<title>{{render_context.email.content.subject}}</title>
<style type="text/css">
/* Add your CSS */
</style>
</head>
<body style="background-color: {{global_fields.email_background_color}}">
<table>
<tr>
<td>
{{children}}
</td>
</tr>
</table>
</body>
</html>

Fields you add to the container component are global fields. They’re for settings that apply to the whole email, such as a background color or a theme. In the email editor, people edit them in the Global fields section.

To use a global field, add global_fields. in front of its Liquid variable. Global fields work in the container component and in every other component. For example, if the container has a color field with the Liquid variable email_background_color:

<td style="background-color: {{global_fields.email_background_color}}">

On other components, the Fields tab lists the global fields you can use under Global Fields. For an example, see Let people switch between themes.

A template can contain multiple top-level elements or bare text; it doesn’t need a wrapper.

Every template must:

  • Be valid Liquid. Every {% if %} needs an {% endif %}, every {% for %} needs an {% endfor %}, and so on.
  • Be no larger than 75 KB. The container component can be up to 150 KB.

If a template has a Liquid error, the top bar of Component Builder shows Liquid template errors and the preview shows the error message. You can’t apply your changes until you fix it.