Template Expressions & Functions
Expressions let you compute values directly inside your templates. Instead of calculating totals or formatting data before sending it to the API, you can do it right in the template using simple functions and operators.
Arithmetic operators
Section titled “Arithmetic operators”You can use standard math operators inside any {{ }} variable block:
| Operator | Example | Result |
|---|---|---|
+ | {{price + tax}} | Addition |
- | {{total - discount}} | Subtraction |
* | {{items.qty * items.price}} | Multiplication |
/ | {{amount / 2}} | Division |
For example, to show the line total in an invoice table row:
{{items.qty * items.unit_price}}This multiplies quantity by unit price for each row automatically.
Built-in functions
Section titled “Built-in functions”Row-level functions
Section titled “Row-level functions”These functions work on individual values. When used with array fields (like items.qty), they repeat automatically for each row.
| Function | Syntax | What it does |
|---|---|---|
mul | {{mul(a, b)}} | Multiply two values |
add | {{add(a, b, c)}} | Add multiple values |
sub | {{sub(a, b)}} | Subtract b from a |
div | {{div(a, b)}} | Divide a by b |
Example — calculate a line total with a discount:
{{sub(mul(items.qty, items.unit_price), items.discount)}}Aggregate functions
Section titled “Aggregate functions”These functions operate on an entire array and return a single value. They do not trigger row repetition.
| Function | Syntax | What it does |
|---|---|---|
sum | {{sum(items.amount)}} | Sum all values of a field |
sumproduct | {{sumproduct(items.qty, items.price)}} | Multiply two fields row by row, then sum the results |
count | {{count(items)}} | Number of items in a list |
avg | {{avg(items.price)}} | Average of a field |
min | {{min(items.price)}} | Smallest value |
max | {{max(items.price)}} | Largest value |
Example — show the invoice total:
{{sum(items.amount)}}Sumproduct
Section titled “Sumproduct”sumproduct multiplies two fields row by row, then sums the results — just like SUMPRODUCT in a spreadsheet.
{{sumproduct(items.qty, items.price)}}For each item, this computes qty × price, then sums all the line totals. This is typically how you compute an invoice subtotal when your data only contains quantity and unit price.
Filters
Section titled “Filters”Filters transform a value after it has been computed. Use the | symbol to apply a filter.
Formatting numbers
Section titled “Formatting numbers”| Filter | Example | Output |
|---|---|---|
round(n) | {{total | round(2)}} | 19.57 |
int | {{value | int}} | 42 |
float | {{value | float}} | 3.14 |
abs | {{value | abs}} | 5 (from -5) |
You can chain filters:
{{items.qty * items.unit_price | round(2)}}Formatting text
Section titled “Formatting text”| Filter | Example | Output |
|---|---|---|
upper | {{name | upper}} | JOHN DOE |
lower | {{name | lower}} | john doe |
capitalize | {{name | capitalize}} | John doe |
title | {{name | title}} | John Doe |
Working with lists
Section titled “Working with lists”| Filter | Example | What it does |
|---|---|---|
length | {{items | length}} | Number of items |
first | {{items | first}} | First item |
last | {{items | last}} | Last item |
join(", ") | {{tags | join(", ")}} | Join items into a string |
sort | {{items | sort}} | Sort items |
reverse | {{items | reverse}} | Reverse order |
Conditionals
Section titled “Conditionals”You can show or hide content based on conditions:
{% if payment_status == "paid" %} Paid ✓{% else %} Payment pending{% endif %}You can also use elif for multiple conditions:
{% if total > 1000 %} Premium order{% elif total > 500 %} Standard order{% else %} Small order{% endif %}Available comparison operators: ==, !=, <, >, <=, >=
Logical operators: and, or, not
Practical examples
Section titled “Practical examples”Invoice subtotal, tax, and total
Section titled “Invoice subtotal, tax, and total”Subtotal: {{sumproduct(items.qty, items.unit_price) | round(2)}}Tax (10%): {{sumproduct(items.qty, items.unit_price) * 0.1 | round(2)}}Total: {{sumproduct(items.qty, items.unit_price) * 1.1 | round(2)}}Item count
Section titled “Item count”{{count(items)}} items in this orderConditional message
Section titled “Conditional message”{% if count(items) > 10 %} Bulk order — thank you!{% endif %}Good to know
Section titled “Good to know”- Missing variables render as empty — no error is shown in the generated PDF.
- Division by zero returns empty instead of crashing.
- Floating-point rounding is handled automatically (e.g.
48.18000000000001becomes48.18). - Aggregate functions (
sum,avg,min,max,count) never trigger row repetition. Row-level functions (mul,add,sub,div) do when referencing array fields.
Next steps
Section titled “Next steps”- Data Binding — How to define variables and pass data to your templates
- Tables — Dynamic tables that grow with your data
- System Variables — Built-in variables for dates and page numbers