STE Filters
STE provides a rich set of built-in filters for transforming and formatting data in your templates. Apply them with the pipe operator:
{{ value | filterName }}
{{ value | filterName(arg1, arg2) }}
Filter Reference
abs
Converts a number to its absolute value.
{{ -42 | abs }} → 42
capitalize
Capitalises the first character of a string.
{{ "hello world" | capitalize }} → "Hello world"
chunk
Splits an array into sub-arrays of the specified size.
{{ [1,2,3,4,5] | chunk(2) }} → [[1,2],[3,4],[5]]
{{#set rows = products | chunk(3)}} {{#each rows}}
<div class="row">
{{#each1 this}}
<div class="col">{{this.name}}</div>
{{/each1}}
</div>
{{/each}}
currency
Formats a number as currency. Defaults to $.
{{ 42.5 | currency }} → "42.50 $"
{{ 42.5 | currency("€") }} → "42.50 €"
cycle
Creates a cycle through values. Use with next.
{{#set altClass = "alt" | cycle("odd", "even")}}
{{#each items}}
<div class="{{ altClass | next }}">{{this}}</div>
{{/each}}
dateFormat
Formats a date. Default format: YYYY-MM-DD. The optional boolean parameter controls UTC (true, default) vs local time (false).
{{ date | dateFormat }}
→ "2024-02-14"
{{ date | dateFormat("DD/MM/YYYY HH:mm") }}
→ "14/02/2024 15:30"
{{ date | dateFormat("MMMM D, YYYY") }}
→ "February 14, 2024"
{{ date | dateFormat("h:mm a") }}
→ "3:30 pm"
Format Tokens
| Token | Output | Description |
|---|---|---|
YYYY / yyyy |
2024 |
Full year |
YY / yy |
24 |
2-digit year |
MMMM / mmmm |
February |
Full month name |
MMM / mmm |
Feb |
Short month name |
MM |
02 |
Zero-padded month |
M |
2 |
Month number |
DD / dd |
09 |
Zero-padded day |
D / d |
9 |
Day number |
dddd |
Wednesday |
Full weekday |
ddd |
Wed |
Short weekday |
HH / hh |
08 |
Zero-padded 24h hour |
H / h |
8 |
24h hour |
mm |
05 |
Zero-padded minutes |
m |
5 |
Minutes |
ss |
09 |
Zero-padded seconds |
s |
9 |
Seconds |
A |
AM / PM |
Uppercase meridiem |
a |
am / pm |
Lowercase meridiem |
Z |
+05:30 |
Timezone offset |
Localisation
Pass a locale object as the fourth argument:
const frenchLocale = {
monthNames: ["janvier", "février", "mars" /* ... */],
monthNamesShort: ["janv", "févr", "mars" /* ... */],
weekdayNames: ["dimanche", "lundi" /* ... */],
weekdayNamesShort: ["dim", "lun" /* ... */],
}
// In template: {{ date | dateFormat("dddd D MMMM YYYY", false, frenchLocale) }}
// → "mercredi 14 février 2024"
defaults
Returns the first non-null, non-undefined value.
{{ null | defaults(undefined, "", "fallback") }} → "fallback"
dump
Pretty-prints a value as JSON. Useful for debugging.
{{ object | dump }}
escape
Escapes HTML special characters.
{{ "<div>" | escape }} → "<div>"
fileSize
Converts bytes to a human-readable size.
{{ 1024 | fileSize }} → "1 KB"
{{ 1048576 | fileSize }} → "1 MB"
first
Returns the first element of an array or first character of a string.
{{ [1, 2, 3] | first }} → 1
{{ "hello" | first }} → "h"
groupBy
Groups an array of objects by a key. Supports dot and bracket notation for nested properties.
{{ users | groupBy("country") }}
{{ posts | groupBy("frontmatter.category") }}
{{ data | groupBy("metadata['group-id']") }}
has
Checks if a value exists in an array, object, or string.
{{ object | has("property") }} → true/false
{{ "hello world" | has("world") }} → true
int
Converts a value to an integer.
{{ "42.9" | int }} → 42
join
Joins array elements with a separator. Optional second argument sets the last separator.
{{ ["a", "b", "c"] | join(", ") }} → "a, b, c"
{{ ["a", "b", "c"] | join(", ", " and ") }} → "a, b and c"
last
Returns the last element of an array or last character of a string.
{{ [1, 2, 3] | last }} → 3
{{ "hello" | last }} → "o"
length
Returns the length of a string, array, or number of keys in an object.
{{ "hello" | length }} → 5
{{ [1, 2, 3] | length }} → 3
log
Logs a value to the console and returns it unchanged. For debugging.
{{ value | log("label") }}
lowercase
{{ "HELLO" | lowercase }} → "hello"
next
Advances and returns the next value in a cycle.
{{ cycleId | next }}
numberFormat
Formats large numbers with suffixes.
{{ 1500000 | numberFormat }} → "1.5M"
preserveSpaces
Converts spaces to entities for HTML rendering.
{{ "hello world" | preserveSpaces }}
range
Checks if a number is within a range. Third boolean argument makes it inclusive.
{{ 5 | range(1, 10) }} → true
{{ 15 | range(1, 10) }} → false
{{ 20 | range(20, 30, true) }} → true
removeSpaces
Removes all whitespace from a string.
{{ "hello world" | removeSpaces }} → "helloworld"
replace
Replaces all occurrences of a substring.
{{ "hello world" | replace("world", "there") }} → "hello there"
reverse
Reverses a string or array.
{{ "hello" | reverse }} → "olleh"
{{ [1,2,3] | reverse }} → [3,2,1]
round
Rounds to the specified number of decimal places.
{{ 3.14159 | round(2) }} → 3.14
safeStringify
Safely converts an object to JSON, replacing circular references with "[Circular]".
{{ complexObject | safeStringify }}
skip
Skips the first N elements (positive) or last N elements (negative).
{{ [10,20,30,40] | skip(2) }} → [30, 40]
{{ [10,20,30,40] | skip(-2) }} → [10, 20]
{{#set regularPosts = posts | skip(1)}} {{#set page3 = allItems | skip(20) | take(10)}}
slice
Returns a portion of an array between start and end indices. Supports negative indices.
{{ [10,20,30,40,50] | slice(1, 3) }} → [20, 30]
{{ [10,20,30,40,50] | slice(-3, -1) }} → [30, 40]
{{ [10,20,30,40,50] | slice(2) }} → [30, 40, 50]
{{#set pageItems = allItems | slice(pageStart, pageEnd)}} {{#set lastThree = items | slice(-3)}}
slugify
Converts a string to a URL-friendly slug.
{{ "Hello World!" | slugify }} → "hello-world"
sortBy
Sorts an array of objects by a key. Default order is "asc". Supports nested properties.
{{ users | sortBy("name") }}
{{ users | sortBy("name", "desc") }}
{{ posts | sortBy("frontmatter.date", "desc") }}
sortByDate
Sorts an array of objects by a date field. Ensures proper date comparison.
{{ posts | sortByDate("date") }}
{{ posts | sortByDate("frontmatter.publish_date", "desc") }}
take
Returns the first N elements (positive) or last N elements (negative).
{{ [10,20,30,40] | take(2) }} → [10, 20]
{{ [10,20,30,40] | take(-2) }} → [30, 40]
{{#set featured = posts | take(3)}} {{#set recent = comments | take(-5)}} {{#set topRated = products | sortBy("rating",
"desc") | take(4)}}
timeAgo
Converts a date to a relative time string.
{{ date | timeAgo }} → "2 hours ago"
toLink
Creates an HTML link.
{{ "https://example.com" | toLink("Visit") }}
→ '<a href="https://example.com">Visit</a>'
{{ "https://example.com" | toLink("Visit", true, true) }}
→ '<a href="https://example.com" target="_blank" rel="external noopener noreferrer">Visit</a>'
trim
Removes whitespace from both ends of a string.
{{ " hello " | trim }} → "hello"
truncate
Truncates to a character limit, appending "...".
{{ "Long text here" | truncate(5) }} → "Long..."
truncateWords
Truncates to a word limit.
{{ "The quick brown fox" | truncateWords(2) }} → "The quick..."
type
Returns the JavaScript type of a value.
{{ value | type }} → "string", "number", "object", etc.
uppercase
{{ "hello" | uppercase }} → "HELLO"
where
Filters an array of objects by a property value. Supports nested properties.
{{ users | where("active", true) }}
{{ posts | where("frontmatter.published", true) }}
wordCount
Counts words in a string.
{{ "hello world" | wordCount }} → 2
Filter Chaining
Pipe multiple filters together — the output of each becomes the input for the next:
{{ "HELLO WORLD" | lowercase | capitalize }}
→ "Hello world"
{{ [1,2,3] | reverse | join(", ") }}
→ "3, 2, 1"
{{ user.name | defaults("Anonymous") | uppercase }}
→ "ANONYMOUS"
{{ items | where("active", true) | sortBy("date") | take(10) }}
Performance Guide
By filter complexity
| Category | Filters | Complexity | Safe up to |
|---|---|---|---|
| High performance | slice, take, skip, chunk |
O(n) | 10,000+ items |
| Moderate | sortBy, groupBy, where |
O(n) to O(n log n) | ~1,000 items |
Recommended chaining order
<!-- ✅ Filter first, then sort the smaller result -->
{{#set result = items | where("status", "active") | sortBy("date") | take(10)}}
<!-- ❌ Sorting everything before filtering is wasteful -->
{{#set result = items | sortBy("date") | where("status", "active") | take(10)}}
Server-side vs template filters
| Operation | Small (<100) | Medium (100–1k) | Large (1k+) |
|---|---|---|---|
| Pagination | Either | slice in template |
Server-side |
| Sorting | Either | sortBy in template |
Server-side |
| Filtering | Either | where in template |
Server-side |
| Grouping | Either | groupBy in template |
Server-side |
| Taking/Skipping | Template | Template | Either |
| Chunking | Template | Template | Template |
Rule of thumb: if the operation would take over 100ms, move it to the server.