Skip to content

Text Templates

A text template is ordinary text with placeholders in it. Anywhere a component accepts a template — a Text component, a table cell, an email subject, a file name — you write the sentence you want and mark the parts that come from your data.

Invoice {$data.invoiceNumber} for {$data.customer.name}

Everything outside the braces is printed as-is. Everything inside is looked up when the report is generated.

Understanding Placeholders

{$data.order.amount:currency;USD;2|Not priced}
Part Example What it does
Keyword $data Where to look — see Accessing data
Path .order.amount Which value to take from there
Format :currency;USD;2 How to render it — see text formats
Fallback \|Not priced What to print instead when the value is null

Only the keyword and path are required. A format is introduced by a colon, its options are separated by semicolons, and formats can be chained by adding another colon.

Accessing data

Keyword Holds Available
$data Results of the report's data sources Everywhere
$params The report parameters supplied for this run Everywhere
$dict Entries from the report's dictionaries, translated per language Everywhere
$it The current item of a repeating element, or of a job's repeating data source Inside a repeating scope
$record The current row Inside a data table or chart
$group The current group's aggregates In a data table group caption or footer

Reaching for the wrong keyword is the most common reason a placeholder comes out empty: $it does not exist outside a repeating element, and $record does not exist outside a table or chart.

Formatting values

// A short date
{$data.order.purchaseDate:date}

// A date with long month names
{$data.order.purchaseDate:datetime;YYYYMMMMdd}

// A number with two decimals, then a suffix — formats chain with a colon
{$data.item.weight:number;2:suffix; kg}

// Minimum zero and maximum eight decimals, printing "Market" when null
{$data.order.price:n;0;8|Market}

Every available format is listed on the Text Formats page.

A worked example

The template:

Dear {$data.order.customerName},

Thank you for your purchase of {$data.order.productName} on {$data.order.purchaseDate:date}.
The total amount charged was {$data.order.amount:currency;USD;2}.

Best regards,
{$data.order.sellerName}

The data:

{
  "order": {
    "customerName": "John Doe",
    "productName": "Wireless Keyboard",
    "purchaseDate": "April 10, 2024",
    "amount": 45.0,
    "sellerName": "Tech Gadgets Inc."
  }
}

The result:

Dear John Doe,

Thank you for your purchase of Wireless Keyboard on 04/10/2024.
The total amount charged was $45.00.

Best regards,
Tech Gadgets Inc.

Notes

  • Use the Data Explorer to check a path before typing it into a template — it shows the shape of what the data source actually returns
  • A path that does not resolve prints nothing rather than failing the render, so an empty spot in the output usually means a wrong path or the wrong keyword
  • Put translatable wording in a dictionary and reference it with {$dict.…}, rather than writing the same sentence into several templates