Skip to content
← Back to Index

render ​

Renders a Liquid template with structured data. Templates use soft variables: a reference to a field that is absent from the data renders as empty text and its field name is included in warnings.

render is a filter: place the template source to its left and pass the data and optional locale as arguments.

Signature ​

filtrera
import 'liquid'

text |> render (
  data: value,
  locale: text | nothing
) => {
  output: text | nothing
  warnings: [text]
}

Parameters ​

ParameterTypeRequiredDescription
templatetextYesThe Liquid template source (left of render)
datavalueYesData available to the template — typically a record, map, or tuple
localetext | nothingNoBCP-47 formatting locale; absent or unresolvable uses invariant formatting

Pass the data argument explicitly

Pass data positionally — '…' render (model, 'sv-SE') — or name it — '…' render (data = model). Do not pass an unnamed record as the only argument: render ({ name = 'World' }) does not supply that record as data.

Returns ​

A record with two fields:

FieldTypeDescription
outputtext | nothingThe rendered text; nothing when rendering cannot complete
warnings[text]Missing field names and any rendering messages; field values are never included

When rendering cannot complete, output is nothing; it never returns partial output.

Locale-aware filters ​

The locale-aware filters — number, date, instant, duration, and percent — are available in every template. Their defaults come from the selected locale, and number, date, and instant each take an optional positional argument:

FilterDefaultOptional argumentExample
numberThe value's own scale (1 299,5)Decimals{{ total | number: 2 }}
dateThe locale's short-date patternDate format string{{ at | date: 'd MMMM yyyy' }}
instantThe locale's general date-and-time patternDate and time format string{{ at | instant: 'R' }}
percentThe culture's percentage pattern—{{ fraction | percent }}
durationThe duration's literal form—{{ span | duration }}

Without a locale, filters use invariant formatting for predictable, culture-neutral output.

For currency amounts, format the amount before passing it to the template with the text module's formatMoney, then render the resulting text.

HTML safety ​

When rendering HTML, encode interpolated values (the standard escape filter is available) and sanitize the rendered output as appropriate for where it will be used.

Examples ​

Render with a bound model ​

filtrera
import 'liquid'

from 'Hello {{ name }}!' render ({ name = 'World' }, nothing)

// Returns:
// { output = 'Hello World!', warnings = [] }

A missing reference renders empty and warns ​

filtrera
import 'liquid'

from 'Hello {{ name }}!' render ({}, nothing)

// Returns:
// { output = 'Hello !', warnings = ['name'] }

Locale-aware number formatting ​

filtrera
import 'liquid'

from 'Total: {{ total | number }}' render ({ total = 1299.5 }, 'sv-SE')

// Returns:
// { output = 'Total: 1 299,5', warnings = [] }

The group separator is the locale's (a non-breaking space in sv-SE, which can look like a plain space).

Filter defaults follow the locale, arguments override ​

filtrera
import 'liquid'

from 'Sent {{ at | date }}' render ({ at = 2026-10-10 }, 'sv-SE')

// Returns:
// { output = 'Sent 2026-10-10', warnings = [] }
filtrera
import 'liquid'

from 'Sent {{ at | date: ''d MMMM yyyy'' }}' render ({ at = 2026-10-10 }, 'sv-SE')

// Returns:
// { output = 'Sent 10 oktober 2026', warnings = [] }
filtrera
import 'liquid'

from 'Total: {{ total | number: 2 }}' render ({ total = 1299.5 }, 'sv-SE')

// Returns:
// { output = 'Total: 1 299,50', warnings = [] }

Nested records and loops ​

filtrera
import 'iterators'
import 'liquid'

from '{% for line in lines %}{{ line.name }} x{{ line.quantity }} {% endfor %}Total: {{ order.total | number }}' render ({
  order = { total = 1299 },
  lines = [{ name = 'Wool Beanie', quantity = 2 }, { name = 'Mittens', quantity = 1 }]
}, 'sv-SE')

// Returns:
// { output = 'Wool Beanie x2 Mittens x1 Total: 1 299', warnings = [] }

A malformed template hard-fails ​

filtrera
import 'liquid'

from 'Hello {% if %}' render ({}, nothing)

// Returns:
// { output = nothing, warnings = ['…'] }

© 2026 Hantera AB. Org. no.: 559242-9582