LiteNode's logo

LiteNode

Docs GitHub logo
▶ Usage

Documentation

STE Template Engine Filters

STE provides a rich set of built-in filters to transform and format data in your templates. Filters are applied using the pipe syntax: {{ value | filterName }} or with arguments: {{ value | filterName(arg1, arg2) }}.

Available Filters

abs

Converts a number to its absolute value.

{{ -42 | abs }} → 42

capitalize

Capitalizes the first character of a string.

{{ "hello world" | capitalize }} → "Hello world"

chunk

Splits an array into chunks (sub-arrays) each of the specified size. Useful for creating grids, pagination, or batching operations.

Basic Usage:

{{ [1,2,3,4,5] | chunk(2) }}
// Outputs: [[1, 2], [3, 4], [5]]

Practical Examples:

<!-- Create a 3-column grid layout -->
{{#set productRows = products | chunk(3)}}
<!-- Iterate over chunks -->
{{#each productRows}}
<div class="row">
    {{#each1 this}}
    <div class="col-4">{{this.name}}</div>
    {{/each1}}
</div>
{{/each}}

<!-- Process items in batches -->
{{#set batches = items | chunk(10)}}
<!-- Iterate over chunks -->
{{#each batches}}
<div class="batch">Processing {{this | length}} items...</div>
{{/each}}

Note: The last chunk may contain fewer elements if the array length is not evenly divisible by the chunk size.

currency

Formats a number as currency with an optional symbol (defaults to $).

{{ 42.5 | currency }} → "42.50 $"
{{ 42.5 | currency("€") }} → "42.50 €"

cycle

Creates a cycle through a set of values, useful for alternating classes or values.

Alternates between "odd" and "even" with each call
{{#set altClass = "alternate" | cycle("odd", "even")}}
{{#each articles}}
    <div class="{{ altClass | next }}">{{ title }}</div>
{{/each}}

dateFormat

Formats a date using the specified format string with enhanced options.

{{ date | dateFormat }}
↪ "2024-02-14" (default format: YYYY-MM-DD)
{{ date | dateFormat("DD/MM/YYYY HH:mm") }}
↪ "14/02/2024 15:30" (custom date and time format)
{{ date | dateFormat("MMMM D, YYYY") }}
↪ "February 14, 2024" (month name format)
{{ date | dateFormat("MMM DD, YY") }}
↪ "Feb 14, 24" (abbreviated format)
{{ date | dateFormat("DDDD, HH:mm") }}
↪ "Wednesday, 15:30" (day of week format)
{{ date | dateFormat("h:mm a") }}
↪ "3:30 pm" (12-hour time format)
{{ date | dateFormat("YYYY-MM-DD", false) }}
↪ "2024-02-14" (using local timezone)

Tokens

A complete list of tokens supported by dateFormat:

Token Example Output Description
YYYY / yyyy 2024 Full year
YY / yy 24 Last two digits of the year
MMMM / mmmm February Full month name
MMM / mmm Feb Abbreviated month name
MM 02 Zero-padded month number
M 2 Numeric month number
DD / dd 09 Zero-padded day of month
D / d 9 Day of month
dddd Wednesday Full weekday name
ddd Wed Abbreviated weekday name
HH / hh 08 Zero-padded hour (24-hour format)
H / h 8 Hour (24-hour format)
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, +00:00 Timezone offset (if useUTC = false)

The boolean optional parameter controls whether to use UTC (true) or local time (false), with UTC being the default.

Localization

An example for french:

const frenchLocale = {
    monthNames: [
        "janvier",
        "février",
        "mars",
        "avril",
        "mai",
        "juin",
        "juillet",
        "août",
        "septembre",
        "octobre",
        "novembre",
        "décembre",
    ],
    monthNamesShort: ["janv", "févr", "mars", "avr", "mai", "juin", "juil", "août", "sept", "oct", "nov", "déc"],
    weekdayNames: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
    weekdayNamesShort: ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"],
}

// Using dateFormat with frenchLocale in a template
dateFormat("2024-02-14", "dddd D MMMM YYYY", false, frenchLocale)
// → "mercredi 14 février 2024"

defaults

Returns the first non-null value from a list of values.

{{ null | defaults(undefined, "", "fallback") }} → "fallback"

dump

Converts a value to a formatted JSON string for debugging.

{{ object | dump }} → Pretty-printed JSON representation

escape

Escapes HTML special characters in a string.

{{ "<div>" | escape }} → "&lt;div&gt;"

fileSize

Formats a number of bytes into 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 specified key. Supports nested properties using dot and bracket notation.

{{ users | groupBy("country") }}
↪ Objects grouped by country property
{{ posts | groupBy("frontmatter.category") }}
↪ Objects grouped by nested category
{{ data | groupBy("metadata['group-id']") }}
↪ Objects grouped by property with special characters

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 specified separators.

{{ ["cherry", "kiwi", "peach"] | join(", ") }} → "cherry, kiwi, peach"
{{ ["cherry", "kiwi", "peach"] | join(", ", " and ") }}
↪ "cherry, kiwi and peach"

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 for debugging (returns the original value).

{{ value | log("Debug label") }} → Logs to console and returns value

lowercase

Converts a string to lowercase.

{{ "HELLO" | lowercase }} → "hello"

next

Used with cycle to get the next value in the cycle.

{{ cycleId | next }} → Gets next value in the previously defined cycle

numberFormat

Formats numbers with suffixes for large values.

{{ 1500000 | numberFormat }} → "1.5M"

preserveSpaces

Preserves all spaces in strings when rendered in HTML by converting them to &nbsp; entities.

{{" Multiple   Spaces   Here " | preserveSpaces}}

range

Checks if a number is within a specified range.

{{ 5 | range(1, 10) }} → true
{{ 15 | range(1, 10) }} → false
{{ 20 | range(20, 30)}} → false
{{ 20 | range(20, 30, true)}} → true (inclusive)

removeSpaces

Removes all whitespace from a string.

{{ "hello world" | removeSpaces }} → "helloworld"

replace

Replaces all occurrences of a substring in a string.

{{ "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 a number to specified decimal places.

{{ 3.14159 | round(2) }} → 3.14

safeStringify

Safely converts an object to JSON string, handling circular references.

{{ complexObject | safeStringify }} → JSON string with "[Circular]" for circular references

skip

Skips the first N elements if N is positive, or skips the last N elements if N is negative, and returns the remaining array. Useful for pagination or excluding certain items.

Basic Usage:

{{ [10, 20, 30, 40] | skip(2) }}
// Outputs: [30, 40]

{{ [10, 20, 30, 40] | skip(-2) }}
// Outputs: [10, 20]

Practical Examples:

<!-- Skip hero post, show the rest -->
{{#set regularPosts = posts | skip(1)}}
<!-- Iterate over posts -->
{{#each regularPosts}}
<article class="regular-post">{{this.title}}</article>
{{/each}}

<!-- Pagination: skip first 20 items for page 3 -->
{{#set page3Items = allItems | skip(20) | take(10)}}

<!-- Exclude admin and moderator roles -->
{{#set regularUsers = users | skip(-2)}}

<!-- Skip header and footer rows in data -->
{{#set dataRows = csvRows | skip(1) | skip(-1)}}

slice

Returns a portion of an array between start and end indices. Supports negative indices (like Python), counting from the end. Most flexible for extracting specific ranges.

Basic Usage:

{{ [10, 20, 30, 40, 50] | slice(1, 3) }}
// Outputs: [20, 30]

{{ [10, 20, 30, 40, 50] | slice(-3, -1) }}
// Outputs: [30, 40]

{{ [10, 20, 30, 40, 50] | slice(2) }}
// Outputs: [30, 40, 50] (from index 2 to end)

Practical Examples:

<!-- Get middle section of articles -->
{{#set middleArticles = articles | slice(2, -2)}}

<!-- Custom pagination -->
{{#set pageStart = (currentPage - 1) * itemsPerPage}}
<!---->
{{#set pageEnd = pageStart + itemsPerPage}}
<!---->
{{#set pageItems = allItems | slice(pageStart, pageEnd)}}

<!-- Get specific range for carousel -->
{{#set carouselItems = images | slice(0, 5)}}

<!-- Extract data without first and last elements -->
{{#set cleanData = rawData | slice(1, -1)}}

<!-- Time-based slicing (if array is date-sorted) -->
{{#set thisWeek = events | slice(-7)}}

Parameter Details:

Common Patterns:

<!-- First half -->
{{#set itemsLength = items | length}}
<!---->
{{#set halfItems = itemsLength / 2}}
<!---->
{{#set firstHalf = items | slice(0, halfItems)}}

<!-- Last 3 items -->
{{#set lastThree = items | slice(-3)}}

<!-- Everything except first and last -->
{{#set middle = items | slice(1, -1)}}

Note: Negative indices count backwards from the end of the array. The slice operation does not modify the original array.

slugify

Converts a string to URL-friendly slug format.

{{ "Hello World!" | slugify }} → "hello-world"

sortBy

Sorts an array of objects by a specified key. Supports nested properties and custom sort order ('asc' by default, 'desc' for descending).

{{ users | sortBy("name") }}
↪ Array sorted by name ascending
{{ users | sortBy("name", "desc") }}
↪ Array sorted by name descending
{{ posts | sortBy("frontmatter.author.name") }}
↪ Array sorted by nested author name
{{ data | sortBy("metadata['priority-order']", "desc") }}
↪ Array sorted by property with special characters

sortByDate

Sorts an array of objects by a date field. Supports nested properties and sort order ('asc' by default, 'desc' for descending). Ensures proper date comparison.

{{ posts | sortByDate("date") }}
↪ Array sorted by date ascending
{{ posts | sortByDate("frontmatter.publish_date", "desc") }}
↪ Array sorted by nested date descending
{{ events | sortByDate("metadata['scheduled-at']") }}
↪ Array sorted by date with special characters

take

Returns the first N elements if N is positive, or the last N elements if N is negative. Perfect for "featured items" or "recent posts" sections.

Basic Usage:

{{ [10, 20, 30, 40] | take(2) }}
// Outputs: [10, 20]

{{ [10, 20, 30, 40] | take(-2) }}
// Outputs: [30, 40]

Practical Examples:

<!-- Show first 3 featured posts -->
{{#set featured = posts | take(3)}}
<!-- Iterate over featured -->
{{#each featured}}
<article class="featured-post">{{this.title}}</article>
{{/each}}

<!-- Show last 5 recent comments -->
{{#set recent = comments | take(-5)}}
<div class="recent-comments">
    {{#each recent}}
    <div class="comment">{{this.text}}</div>
    {{/each}}
</div>

<!-- Combined with other filters -->
{{#set topRated = products | sortBy("rating", "desc") | take(4)}}

timeAgo

Converts a date to a relative time string.

{{ date | timeAgo }} → "2 hours ago"

Creates an HTML link with optional attributes for external links.

{{ "https://example.com" | toLink("Visit Site") }}
↪ '<a href="https://example.com">Visit Site</a>'
{{ "https://example.com" | toLink("Visit Site", true) }}
↪ '<a href="https://example.com" target="_blank">Visit Site</a>'
{{ "https://example.com" | toLink("Visit Site", true, true) }}
↪ '<a href="https://example.com" target="_blank" rel="external noopener noreferrer">Visit Site</a>'

trim

Removes whitespace from both ends of a string.

{{ "  hello  " | trim }} → "hello"

truncate

Truncates a string to specified length.

{{ "Long text here" | truncate(5) }} → "Long..."

truncateWords

Truncates a string to specified number of words.

{{ "The quick brown fox" | truncateWords(2) }} → "The quick..."

type

Returns the JavaScript type of a value.

{{ value | type }} → "string", "number", "object", etc.

uppercase

Converts a string to uppercase.

{{ "hello" | uppercase }} → "HELLO"

where

Filters an array of objects by matching a property value. Supports nested properties using dot and bracket notation.

{{ users | where("active", true) }}
↪ Array of users where active is true
{{ posts | where("frontmatter.published", true) }}
↪ Array of posts where nested published is true
{{ data | where("metadata['user-status']", "approved") }}
↪Array filtered by property with special characters

wordCount

Counts the number of words in a string.

{{ "hello world" | wordCount }} → 2

Filter Chaining

Filters can be chained together using multiple pipe operators. The output of each filter becomes the input for the next filter in the chain.

{{ "HELLO WORLD" | lowercase | capitalize }} → "Hello world"
{{ [1, 2, 3] | reverse | join(", ") }} → "3, 2, 1"
{{ user.name | defaults("Anonymous") | uppercase }}
↪ "ANONYMOUS" (if user.name is null)
{{ price | currency | escape }} → "&#36;42.50"

Best Practices

Performance Considerations by Filter Type

High Performance Filters

These filters (slice, take, skip, chunk) are very efficient and safe to use with larger arrays:

Good uses:

Moderate Performance Filters

These filters (groupBy, sortBy, where) are designed for moderate-sized arrays (typically < 1,000 items):

Good uses:

Avoid:

Small Arrays (< 100 items)

<!-- All filters are safe and fast -->
{{#set sorted = items | sortBy("name") | take(10)}}
<!---->
{{#set grouped = items | groupBy("category") | slice(0, 5)}}

Medium Arrays (100-1,000 items)

<!-- Use pagination with slice/take -->
{{#set pageItems = items | slice(startIndex, endIndex)}}
<!---->
{{#set featured = items | take(5)}}

<!-- Be cautious with sortBy/groupBy -->
{{#set sorted = items | sortBy("priority") | take(20)}}

Large Arrays (1,000+ items)

<!-- Prefer slice/take/skip for performance -->
{{#set recentItems = items | take(-50)}}
<!---->
{{#set pageChunk = items | slice(pageStart, pageEnd)}}

<!-- Avoid heavy operations in templates -->
<!-- ❌ Don't do this: -->
{{#set heavySort = largeArray | sortBy("complex.nested.property")}}

<!-- ✅ Do this instead: Sort on server, then slice -->
{{#set pageData = preSortedArray | slice(offset, limit)}}

Filter Chaining Best Practices

Efficient Chaining Order

<!-- ✅ Good: Filter first, then sort smaller subset -->
{{#set result = items | where("status", "active") | sortBy("date") | take(10)}}

<!-- ❌ Inefficient: Sort everything, then filter -->
{{#set result = items | sortBy("date") | where("status", "active") | take(10)}}

Memory-Conscious Patterns

<!-- ✅ Good: Chain lightweight operations -->
{{#set result = items | skip(10) | take(20) | chunk(5)}}

<!-- ⚠️ Consider impact: Multiple heavy operations -->
{{#set result = items | sortBy("name") | groupBy("type") | sortBy("date")}}

Server-Side vs Client-Side Decision Matrix

Operation Small Arrays Medium Arrays Large Arrays
Pagination Either Client (slice) Server
Sorting Either Client (sortBy) Server
Filtering Either Client (where) Server
Grouping Either Client (groupBy) Server
Taking/Skipping Client Client Either
Chunking Client Client Client

Memory Usage Guidelines

Rule of thumb: If your filter operation would take >100ms to complete, consider moving it server-side.

Content