Filters & Working with Lists

Last updated 23 May 2026

A value flowing through chained Flexie Scripting filters, and a list being grouped and totalled

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 }}
INPUT " maria " | FILTER trim → "maria" | FILTER capitalize → "John" OUTPUT "John"

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