Filters & Working with Lists
Last updated 23 May 2026

What a filter is
A filter transforms a value using the pipe symbol |. The value on the left is fed into the filter on the right:
{{ "hello world" | upper }} → HELLO WORLD
{{ 1234.5 | number_format(2) }} → 1,234.50
Filters chain left to right, each one receives the result of the one before:
{{ first_name | trim | capitalize }}
Everyday formatting filters
These are the standard filters available in Flexie Scripting:
| Filter | What it does | Example → result |
|---|---|---|
upper / lower |
Change case. | {{ "abc" | upper }} → ABC |
capitalize |
Capitalise the first letter. | {{ "john" | capitalize }} → John |
title |
Capitalise Each Word. | {{ "acme ltd" | title }} → Acme Ltd |
trim |
Remove surrounding spaces. | {{ " x " | trim }} → x |
default(x) |
Use a fallback when empty. | {{ phone | default("N/A") }} |
number_format(d, dec, sep) |
Format a number. | {{ 1234.5 | number_format(2) }} → 1,234.50 |
round(p) |
Round a number. | {{ 3.146 | round(2) }} → 3.15 |
abs |
Absolute value. | {{ -5 | abs }} → 5 |
length |
Count items or characters. | {{ invoices | length }} |
join(sep) |
Join a list into text. | {{ ["a","b"] | join(", ") }} → a, b |
split(sep) |
Split text into a list. | {{ "a,b,c" | split(",") }} |
replace({from: to}) |
Replace substrings. | {{ s | replace({"-": " "}) }} |
slice(start, len) |
Take part of a list or string. | {{ items | slice(0, 5) }} |
first / last |
First or last item. | {{ invoices | first }} |
reverse |
Reverse a list or string. | {{ items | reverse }} |
sort |
Sort a list. | {{ names | sort }} |
keys |
The keys of a map. | {{ row | keys }} |
merge(other) |
Combine two lists or maps. | {{ a | merge(b) }} |
nl2br |
Turn line breaks into HTML <br>. |
{{ note | nl2br }} |
striptags |
Remove HTML tags. | {{ html | striptags }} |
escape |
Make text safe for HTML. | {{ userText | escape }} |
raw |
Output without escaping (use with care). | {{ trustedHtml | raw }} |
json_encode |
Turn data into a JSON string. | {{ row | json_encode }} |
url_encode |
Make text URL-safe. | {{ q | url_encode }} |
map, filter, reduce, batch |
Transform, narrow, fold, or chunk a list. | {{ items | filter(i => i.active) }} |
Flexie's own filters
On top of the standard set, Flexie adds these:
| Filter | What it does | Example |
|---|---|---|
cast_int |
Force a value to a whole number (strips commas). | {{ "1,234" | cast_int }} → 1234 |
cast_float(precision=0) |
Force a value to a decimal number. | {{ "12.5" | cast_float(2) }} |
cast_string |
Force a value to text. | {{ 123 | cast_string }} |
cast_bool |
Force a value to true or false. | {{ "1" | cast_bool }} |
slugify(sep="-") |
Make a URL-safe slug. | {{ "Hello World!" | slugify }} → hello-world |
json_decode |
Parse a JSON string into data. | {{ body | json_decode }} |
json_path(expr) |
Extract a nested value by path. | {{ data | json_path("$.total") }} |
regex_replace(pattern, replacement, limit=-1) |
Pattern-based find and replace. | {{ s | regex_replace("/\\s+/", " ") }} |
group_by(key) |
Group a list of records by a field. | {{ deals | group_by("stage") }} |
unique_by(key) |
Drop duplicates by a field. | {{ contacts | unique_by("email") }} |
sum_by(key, scale=4) |
Total a numeric field across records. | {{ items | sum_by("amount") }} |
sort_by(key, dir="ASC") |
Sort records by a field. | {{ invoices | sort_by("due_date", "DESC") }} |
Working across a list of records
You will often fetch many records (with findMany, getSmartListRecords, findDeals, etc.) and then summarise or reshape them. These helpers do that.
Totals and statistics
| Function | What it does |
|---|---|
sumField(list, field) |
Add up one field across a list. |
avgField(list, field) |
Average one field across a list. |
minField(list, key) |
Smallest value of a field. |
maxField(list, key) |
Largest value of a field. |
countDistinct(list, field) |
How many different values a field has. |
{% set invoices = findMany("invoice", "contact_id", id) %}
Total billed: {{ sumField(invoices, "total_incl_tax") | number_format(2) }}
Largest: {{ maxField(invoices, "total_incl_tax") | number_format(2) }}
Reshaping a list
| Function | What it does |
|---|---|
collectionColumn(list, column, indexBy=null) |
Pull a single column out as a flat list, or, with indexBy, build a lookup map keyed by another column. |
{# A flat list of every email on the account #}
{{ collectionColumn(getAccountContacts(id), "email") | join(", ") }}
Looping with grouping, a worked example
Show invoices grouped by status, with a subtotal per group:
{% set invoices = findMany("invoice", "contact_id", id) %}
{% set grouped = invoices | group_by("status") %}
{% for status, rows in grouped %}
{{ status | upper }} ({{ rows | length }})
{% for inv in rows | sort_by("due_date") %}
- {{ inv.number }}: {{ inv.total_incl_tax | number_format(2) }}
{% endfor %}
Subtotal: {{ rows | sum_by("total_incl_tax") | number_format(2) }}
{% endfor %}
Reusable blocks, snippets
If you keep retyping the same chunk of content (a header, a signature, a styled footer), an administrator can save it as a snippet and you include it by name:
{% snippet "email_header" %}
... your content ...
{% snippet "email_footer" %}
A snippet is itself Flexie Scripting, so it can contain its own logic and tokens and will see the same record data as the template that includes it.
Next steps
- Recipes: these pieces assembled into complete solutions.
- Where it runs & its limits: what data is available in each context, and the safety boundaries.