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

PlaceNotes
Send email: subject, message and recipientsThe 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 nameThe content is HTML. The file name is plain text.
Send Slack messageWritten as HTML, then turned into Slack formatting.
Send to webhook: web address, headers and bodyValues only. Loops and conditions are not supported in the body.
TemplatesEmail messages, PDF documents and layouts.
The success message, with Format set to HTML templateSee Form settings.
Heading, paragraph, button and HTML fields with Content mode set to TemplateSee Field types.
Default values and mappings set to TemplateSee 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 with entry:, form:, data_table:, workflow: or iteration:. 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:", "}}
FormatterIn the pickerWhat it doesSetting
valueUses a choice answer’s stored value instead of its label
defaultSet fallback valueUses the setting when the value is emptyThe fallback text
upperConvert to uppercaseCapital letters
lowerConvert to lowercaseSmall letters
capfirstCapitalize first letterCapitalises the first letter
truncatewordsTruncate to N wordsShortens to a number of wordsNumber of words
truncatecharsTruncate to N charactersShortens to a number of charactersNumber of characters
floatformatFormat decimal placesRounds to a number of decimal placesNumber of places, such as 2
yesnoConvert to yes/noWrites a true or false value as wordsTwo words, such as "Yes,No"
pluckExtract fieldTakes one field from each item in a listThe field ID
joinJoin with separatorJoins a list into textThe separator, such as ", "
firstGet first itemThe first item of a list
lastGet last itemThe last item of a list
lengthCount itemsThe number of items in a list
addAdds a numberThe number
slicePart of a listA 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 records of a Find records step: {% for item in {{workflow:current.steps.find_entries.outputs.records}} %}. Each record has its id, created_at and 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:

VariableGives
forloop.CounterThe item’s number, from 1
forloop.Counter0The item’s number, from 0
forloop.FirstTrue for the first item
forloop.LastTrue for the last item
forloop.RevcounterHow many items are left, including this one

For example, {% if not forloop.Last %}, {% endif %} puts a comma between items.

Other tags

TagUse
{% 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 default for 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.

Something missing or unclear? Tell us.