Templates
Template syntax
Reference for the template language in emails, PDFs, Slack messages, success messages and content fields: values, formatters, conditions and loops.
Emails, PDFs, Slack messages, the success message and content fields in Template mode share one template language. The editor writes it for you when you use Insert, + Reference, + For loop or + If else. This page is for when you select Edit as template or Plain and work with the text directly.
Where it is used
| Place | Notes |
|---|---|
| Send email: subject, message and recipients | The message editor accepts ordinary text and saves it as HTML; Edit as template exposes the HTML. Subject and recipients are plain text. |
| Generate PDF: content and file name | The content is HTML. The file name is plain text. |
| Send Slack message | Written as HTML, then turned into Slack formatting. |
| Send to webhook: web address, headers and body | Values only. Loops and conditions are not supported in the body. |
| Templates | Email messages, PDF documents and layouts. |
| The success message, with Format set to HTML template | See Form settings. |
| Heading, paragraph, button and HTML fields with Content mode set to Template | See Field types. |
| Default values and mappings set to Template | See Calculated values and defaults. |
How each place escapes inserted values is described in Inserting values.
Output a value
Put a value inside double braces:
Hello {{entry:current.answers.first_name}}
Order {{entry:current.id}}
Dear {{ template.customer.name }}
Inside the braces you can use:
- A reference, such as
entry:current.answers.first_name. It starts withentry:,form:,data_table:,workflow:oriteration:. The full syntax, with filters, is in Inserting values. - A template value, such as
template.customer.name, in a template from the Templates page. Each step that uses the template fills it in. - A loop variable, such as
item.name, inside a loop.
Choice answers in emails, PDFs, Slack and approval messages show their labels by default. Use |value for the stored value; conditions inside {% %} still use stored values. See Choice labels and stored values.
A value that is missing or empty is written as nothing. Numbers are written without trailing zeros, so 12 shows as “12”, not “12.000000”, unless you format them yourself.
Formatters
Add a formatter after |. Give it a setting after :. Chain several from left to right.
{{entry:current.answers.total|floatformat:2}}
{{ template.customer.name|default:"Customer" }}
{{entry:current.answers.line_items|pluck:"name"|join:", "}}
| Formatter | In the picker | What it does | Setting |
|---|---|---|---|
value | Uses a choice answer’s stored value instead of its label | ||
default | Set fallback value | Uses the setting when the value is empty | The fallback text |
upper | Convert to uppercase | Capital letters | |
lower | Convert to lowercase | Small letters | |
capfirst | Capitalize first letter | Capitalises the first letter | |
truncatewords | Truncate to N words | Shortens to a number of words | Number of words |
truncatechars | Truncate to N characters | Shortens to a number of characters | Number of characters |
floatformat | Format decimal places | Rounds to a number of decimal places | Number of places, such as 2 |
yesno | Convert to yes/no | Writes a true or false value as words | Two words, such as "Yes,No" |
pluck | Extract field | Takes one field from each item in a list | The field ID |
join | Join with separator | Joins a list into text | The separator, such as ", " |
first | Get first item | The first item of a list | |
last | Get last item | The last item of a list | |
length | Count items | The number of items in a list | |
add | Adds a number | The number | |
slice | Part of a list | A range, such as ":3" for the first three |
Choose a value offers formatters when you insert a list, under Add formatters, so you can turn it into one value. Type the others in Edit as template.
Show something only in some cases
{% if template.total > 1000 %}
Priority order
{% elif template.total > 0 %}
Standard order
{% else %}
No charge
{% endif %}
To test a reference, put it in double braces inside the tag:
{% if {{entry:current.answers.status}} == "approved" %}
Your request was approved.
{% endif %}
Comparisons are ==, !=, >, >=, < and <=. Combine them with and, or and not. Put text in double quotes. Formatter text settings also accept single quotes or unquoted text.
Repeat for each item
{% for item in {{entry:current.answers.line_items}} %}
{{ item.name }}: £{{ item.price|floatformat:2 }}
{% endfor %}
The name after for is yours to choose. Inside the loop, use it to reach the item’s fields. You can loop over:
- A repeating group’s answers, as above.
- The
recordsof a Find records step:{% for item in {{workflow:current.steps.find_entries.outputs.records}} %}. Each record has itsid,created_atand a value for each column or question, by ID. - A list template value, such as
{% for item in template.items %}.
Inside a loop you can also use:
| Variable | Gives |
|---|---|
forloop.Counter | The item’s number, from 1 |
forloop.Counter0 | The item’s number, from 0 |
forloop.First | True for the first item |
forloop.Last | True for the last item |
forloop.Revcounter | How many items are left, including this one |
For example, {% if not forloop.Last %}, {% endif %} puts a comma between items.
Other tags
| Tag | Use |
|---|---|
{% set total = 0 %} | Stores a value to use later in the template |
{% with name = template.customer.name %}…{% endwith %} | Gives a value a short name inside a section |
{% comment %}…{% endcomment %} | A note that is not written out |
Other tags, such as include, extends and macro, are not allowed. A template that uses one fails when it runs.
Template values
In a template on the Templates page, every template.<name> you use becomes a value that steps must fill in. Dots make groups: template.customer.name and template.customer.email both sit under customer. A value you loop over becomes a list.
The Values tab shows them, and each step lists them under Template data. Keep the names stable once steps use the template.
Layouts
A layout is a template with {{ content }} where the email or PDF goes:
<div style="max-width:640px;margin:0 auto;font-family:Arial,sans-serif">
<p><strong>Example Ltd</strong></p>
{{ content }}
<p style="font-size:12px">You are receiving this because you filled in one of our forms.</p>
</div>
{{ content }} is reserved for this. A layout can’t be saved without it.
HTML
In email and PDF content, the success message and HTML fields, write normal HTML with inline styles. Inserted values are escaped, so an answer shows as text even if it contains tags. The success message and HTML fields are also cleaned before they are shown: scripts, event handlers, unsafe links and custom styles are removed. PDF templates are also sanitised before rendering.
Check your template
- Test automations with realistic answers, including empty ones, and check the result in Runs and testing.
- Use
defaultfor values that may be empty. - Check that conditions and loops still leave valid HTML when they remove a section.
- For the success message, submit the form in preview to see it.
A template stops with an error if it takes longer than 2 seconds to fill in or produces more than 4 MB of text. Keep loops to the items you need.