Variables (also called personalization tags or merge tags) let you insert personalized data for each recipient, like their first name or most recent purchase. Filters modify how this data appears.
How to use filters?
You use filters inside double curly braces {{ }} with a pipe |. For example:
| Input | Output |
| {{ contact.FIRSTNAME|upper }} | EMILIA |
You can chain multiple filters, so that the output of one filter is passed to the next. For example:
| Input | Output |
| {{ contact.FIRSTNAME|title|truncatechars:4 }} | EMIL |
To insert a variable with filters in a message, you can either:
-
Type the variable and filters manually, or
-
Select an existing variable and edit its syntax in the Advanced settings tab.
💬 Insert a default value
default
Inserts a fallback value if a variable is empty.
| Input | Output |
| Hello {{ contact.FIRSTNAME|default:'there' }}, | Hello there, |
🔠 Format word case
capfirst
Capitalizes the first character.
| Input | Output |
| {{ contact.MESSAGE|capfirst }} | My red car |
title
Capitalizes the first letter of each word.
| Input | Output |
| {{ contact.FULLNAME|title }} | John Doe |
upper
Converts all characters to uppercase.
| Input | Output |
| {{ contact.FULLNAME|upper }} | JOHN DOE |
lower
Converts all characters to lowercase.
| Input | Output |
| {{ contact.FULLNAME|lower }} | john doe |
truncatechars
Shortens a string to N characters. Truncated values end with an ellipsis (…) included in the character count.
| Input | Output |
| {{ contact.MANAGER|truncatechars:7 }} | Elisab… |
🔢 Format numbers
floatformat
Rounds float values to a specified number of decimals.
| Input | Output |
| {{ params.total|floatformat:2 }} | 40.32 |
| {{ params.total|floatformat:0 }} | 40 |
integer
Converts a number in string or floating point format into an integer number.
| Input | Output |
| {{ 10.578|integer }} | 10 |
| {{ "16.765"|integer }} | 16 |
float
Converts a number in string or integer format into a floating point number.
| Input | Output |
| {{ 10|float }} | 10.000000 |
| {{ "16.765"|float }} | 16.765000 |
lang_format
Formats numbers according to a language.
| Input | Output |
| {{ params.number|lang_format:"fr" }} | 123 456,789 |
| {{ params.number|lang_format:"en" }} | 123,456.789 |
| {{ params.number|lang_format:"hi" }} | 1,23,456.789 |
| {{ params.number|lang_format:"bn" }} | ১,২৩,৪৫৬.৭৮৯ |
| {{ params.number|lang_format:"fr,%.2f" }} | 123 456,79 |
-
To force 2 decimals, add
,%.2fafter the language filter. - For French, the thousands separator is a non-break space.
📅 Format date and time
time_parse
- Day and month names (full and abbreviated) must be in English.
- The reference time is "Monday January 2 15:04:05 -0700 MST 2006".
- Missing values default to 0.
- The default timezone is UTC.
- The am/pm keywords can be used.
- Timezones can be keywords (MST, CET, UTC, Asia/Kolkata) or numeric offsets (+0100, -0100).
Converts a date string into a standard timestamp that can be used with other filters, like date or date_i18n.
When passing your date format as an argument, write the date and time exactly as the reference time would look if it were the value.
| Input | Output |
| {{ params.MY_DATE|time_parse:"Monday 02 January 2006" }} | Tuesday 11 March 2021 |
Use time_parse_rfc3339 for RFC3339-formatted strings without providing a custom format.
date
Converts a timestamp or parsed date into a specified format. Use it with a date parsed via time_parse or with the current time using time_now.
| Input | Output |
| {{ "14:01 01/06/2018"|time_parse:"15:04 02/01/2006"|date:"Mon Jan 2 15:04:05 2006" }} | Fri Jun 1 14:01:00 2018 |
| {{ time_now|date:"Monday, Jan 2, 2006" }} | Will print the current day and date in the specified format |
| {{ time_now|date:"02/01/2006" }} | Will print the current day and date in the specified format |
| {{ time_now|date:"01" }} | Will print the current month |
| {{ time_now|date:"02" }} | Will print the current day |
| {{ time_now|date:"2006" }} | Will print the current year |
date_i18n
Converts a timestamp or parsed date into a specified format, with the output displayed in a specified language. This filter works like date, but you must specify the language first, followed by the format.
Supported languages are en, fr, it, es, de, and pt.
| Input | Output |
| {{ "14:01 01/06/2018" | time_parse:"15:04 02/01/2006"|date_i18n:"en,Monday" }} | Friday |
| {{ "14:01 01/06/2018" | time_parse:"15:04 02/01/2006"|date_i18n:"de,Monday" }} | Freitag |
time_add_date
Adds years, months, and days to a timestamp or parsed date. You must specify the time to add in the order year, month, day.
| Input | Output |
| {{ time_now|time_add_date:"1,2,3" }} | Will print timestamp after adding 1 year, 2 months, and 3 days to the current timestamp |
| {{ "14:01 01/06/2018"|time_parse:"15:04 02/01/2006"|time_add_date: "1,2,3" }} | 2019-08-04 14:01:00 +0000 UTC |
time_in_location
Converts a timestamp or parsed date to a specified timezone. You must specify the timezone in the format location/timezone.
| Input | Output |
| {{ time_now|time_in_location:"Europe/Berlin" }} | Will print current timestamp in CEST |
| {{ "14:01 01/06/2018"|time_parse:"15:04 02/01/2006"|time_in_location: "Europe/Berlin" }} | 2018-06-01 16:01:00 +0200 CEST |
time_add_duration
Adds hours, minutes, and seconds to a timestamp or parsed date. You must specify the value in the format h,m,s and pass at least one value (hour, minute or second) in the filter.
| Input | Output |
| {{ time_now|time_add_duration:"1h2m3s" }} | Will print timestamp after adding 1 hour, 2 minutes, and 3 seconds to the time value in the current timestamp |
| {{ time_now|time_add_duration:"30m" }} | Will print timestamp after adding 30 minutes to the time value |
time_unix
Converts a time value to Unix timestamp in seconds.
| Input | Output |
| {{ time_now|time_unix }} | Will print current Unix timestamp in seconds |
time_unix_nano
Converts a time value to Unix timestamp in nanoseconds.
| Input | Output |
| {{ time_now|time_unix_nano }} | Will print current Unix timestamp in nanoseconds |
🧑💻 Encode or encrypt data
base64_encode or decode
Encodes or decodes base 64:
- base64_decode decodes a string to a []byte
- base64_encode encodes a []byte to a string
| Input | Output |
| https://example.com/test?name={{ contact.FIRSTNAME|base64_encode }} | https://example.com/test?name=RW56bw== (instead of https://example.com/test?name=Enzo) |
The base64_encode and decode filters can take an optional encoding parameter:
- std: normal base64 encoding.
- raw_std: normal base64 encoding, without the = padding characters.
- url: URL safe version of base64 encoding, + and / are replaced with - and _ respectively.
- raw_url: a combination of raw and url.
aes_128, 192, or 256
Encrypts a value. For example, you can use this filter to send encrypted contact information in a URL, such as an email address or an ID.
The AES variant used depends on the length of the provided key:
| Secret Key Length | AES Variant |
| 16 bytes (128 bits) | AES-128 |
| 24 bytes (192 bits) | AES-192 |
| 32 bytes (256 bits) | AES-256 |
For example, for the AES-256 variant, the variable has to be formatted as {{ contact.ATTRIBUTE | aes_256:"key" }}, where the key:
- Has to be 32 digits.
- Has to be randomly generated.
- Has to be persisted on your end to decrypt the original value.
By default, if no encoding parameter is added, base64 std will be used. Otherwise, it also supports:
- raw_std: normal base64 encoding, without the = padding characters.
- url: URL safe version of base64 encoding, + and / are replaced with - and _ respectively.
- raw_url: a combination of raw and url.
In our examples below, we are encrypting the email addresses of our contacts using the following key: e5a34a481274c776856d04119bed8188. Note that you should not use the same key and instead generate your own key following the above requirements.
| Encoding | Input | Output |
| No encoding (default base64 encoding std) | {{ contact.EMAIL | aes_256:"e5a34a481274c776856d04119bed8188" }} | Will print a random string that needs to be decrypted to read the original value |
| Base64 encoding raw_std | {{ contact.EMAIL | aes_256:"e5a34a481274c776856d04119bed8188,raw_std" }} | Will print a random string that needs to be decrypted to read the original value |
| Base64 encoding url | {{ contact.EMAIL | aes_256:"e5a34a481274c776856d04119bed8188,url" }} | Will print a random string that needs to be decrypted to read the original value |
| Base64 encoding raw_url | {{ contact.EMAIL | aes_256:"e5a34a481274c776856d04119bed8188,raw_url" }} | Will print a random string that needs to be decrypted to read the original value |
🔎 Other filters
first
Returns the first item of a sequence, a mapping, or a string.
| Input | API request | Output |
| {{ params.array|first }} | "params" : { "array" : [ 1,2,3,4 ] } |
1 |
join
Combines the items in an array into a single string using the argument as a separator.
The separator between elements is empty by default. You may define it with the optional first parameter.
| Input | Output |
| {{ [1, 2, 3]|join }} | 123 |
| {{ [1, 2, 3]|join: '|' }} | 1|2|3 |
last
Returns the last item of a sequence, a mapping, or a string.
| Input | Output |
| {{ [1, 2, 3, 4]|last }} | 4 |
length
Returns the number of items of a sequence or a mapping, or the length of a string.
| Input | Output |
| {{ ['a', 'b', 'c', 'd']|length }} | 4 |
safe
Marks a string as not requiring further HTML escaping prior to output.
| A | API request | Input | Output | |
| "params" :{HtmlTest: "<p>This is my test sentence.</p>"} | {{ params.htmltest|safe }} | This is my test sentence | ||
| B | Contact attribute | Placeholder | Input | Output |
| EMAIL_SALUTATION | Welcome to <b>Brevo</b>, we're glad to have you here | {{ contact.EMAIL_SALUTATION|safe }} | Welcome to Brevo, we're glad to have you here | |
Without the safe filter, the HTML tags would be displayed as a normal string in the recipient’s email: "<p>This is my test sentence</p>" or "Hello from <b>Brevo</b>, nice to have you here".
slice
Extracts a slice of a sequence, a mapping, or a string.
This filter may be configured to:
| A | Loop through only the first "n" number of elements in an array | In both of these cases, remember that elements in an array are assigned a unique position number starting with "0" as the first position (they are "zero-indexed"). |
| B | Loop through elements between two specified positions ("n" and "m") in the array | |
| C | Loop through elements between two specified elements in an array. |
In each example, consider that your array contains the following: ["a","b","c","d","e","f","g","h"...].
| Input | Output | |
| A |
{% for product in params.products|slice:':5' %} {{ product.name }} - {{ product.price }} {% endfor %} |
Will loop over the first 5 positions (0-4), which are: ["a","b","c","d","e"] |
| B |
{% for product in params.products|slice:'2:3' %} {{ product.name }} - {{ product.price }} {% endfor %} |
Will loop over positions (2-3), which are: ["c","d"] |
| C |
{% for product in params.products|slice:'b:d' %} {{ product.name }} - {{ product.price }} {% endfor %} |
Will loop over the specified elements, which are: ["b","c","d"] |
verbatim
In Brevo, variables are written using double curly brackets like {{ params.property }}. When you include double curly brackets like {{ this }} in your email, Brevo treats it as a template element.
To display {{ }} as plain text in your email, wrap the content in a {% verbatim %} block:
| Input | Output |
|---|---|
|
{% verbatim %} {{ Print variable }} {% endverbatim %} |
{{ Print variable }} |
autoescape
By default, Brevo escapes all variable content, including HTML and JavaScript. This means that if your variable contains HTML (e.g., <h1>My title</h1>), it will be displayed as plain text rather than rendered as HTML.
To allow HTML rendering, you need to disable auto-escaping using the {% autoescape off %} tag. Wrap the variable in this block and close it with {% endautoescape %}:
{% autoescape off %}{{ params.my_html }}{% endautoescape %}
| Input | Output | |
|---|---|---|
| Without the autoescape tag | {{ params.my_html }} | <h1>My title</h1> |
| With the autoescape tag |
{% autoescape off %} {{ params.my_html }} {% endautoescape %} |
My title |
📖 Additional resources
Brevo Template Language is based on Pongo2, which is a re-implementation of Django in Go (a programming language).
All supported tags
autoescape, comment, cycle, filter, firstof, for, if, ifchanged, now, set, spaceless, templatetag, with.
All supported filters
escape, safe, escapejs, add, addslashes, capfirst, center, cut, date, default, default_if_none, divisibleby, first, floatformat, get_digit, iriencode, join, last, length, length_is, linebreaks, linebreaksbr, linenumbers, ljust, lower, make_list, phone2numeric, pluralize, random, removetags, rjust, slice, stringformat, striptags, time, title, truncatechars, truncatechars_html, truncatewords, truncatewords_html, upper, urlencode, urlize, urlizetrunc, wordcount, wordwrap, yesno.
All supported filters for hash algorithms
hash_md5, hash_sha256, hash_sha256_224, hash_sha512, hash_sha512_224, hash_sha512_256, hash_sha512_384, hash_sha3_224, hash_sha3_256, hash_sha3_384, hash_sha3_512.
🤔 Have a question?
If you have a question, feel free to contact our support team by creating a ticket from your account. If you don't have an account yet, you can contact us here.
If you’re looking for help with a project using Brevo, we can match you with the right certified Brevo Agency partner.