Template syntax
T-pilot templates are ordinary documents with {{ }} tags. This page describes the template language. Templates written for the original tag format ({{List.Field}}) keep working unchanged.
The syntax on this page works in Word, Excel, PowerPoint, OpenDocument (Writer, Calc, Impress), HTML, Markdown, text, XML and JSON templates.
Values
{{Invoice.Number}}
{{ invoice . number }} same tag: names ignore case and the spaces around dots
{{Lines[0].Description}} an item of a list (also written Lines.0.Description)
- If a tag has no value, it stays in the document exactly as written, so you can see what didn't fill.
- A name with spaces works as long as it has no operator symbols:
{{Due Date}}. - To write a literal
{{, use{{"{{"}}.
Names T-pilot provides:
| Name | Value |
|---|---|
{{ListName.Field}} | A field of the chosen SharePoint item. The list name keeps only letters, digits and _. |
{{ChildList.Field}} | A field of a linked child list. Inside a table row it repeats once per child item. |
{{Person_Name}}, {{Person_Email}} | A person field's name and email. |
{{Config.Key}} | A custom placeholder from Configuration. |
{{System.Today}}, {{System.Now}} | Today's date, and the current date and time, in the organization's culture. |
Filters
Use | to send a value through filters, applied left to right. Arguments go after : and are separated by commas.
{{Invoice.Total | currency:"INR"}}
{{Invoice.Date | date:"dd MMM yyyy" | upper}}
{{Customer.Email | default:"—"}}
| Filter | Example | Result |
|---|---|---|
upper, lower, trim | {{Name | upper}} | ACME LTD |
title, capitalize | {{Name | title}} | Acme Ltd |
padLeft:n[,char], padRight | {{No | padLeft:4,"0"}} | 0042 |
substr:start[,length] | {{Code | substr:0,3}} | INV |
replace:old,new | {{Ref | replace:"/","-"}} | |
truncate:n[,suffix] | {{Notes | truncate:40}} | … is added when the text is cut |
prepend:text, append:text | {{Pct | append:"%"}} | |
default:text (also ifEmpty) | {{Phone | default:"n/a"}} | Used when the value is empty or missing |
yesno[:yes,no[,empty]] | {{Paid | yesno:"Paid","Due"}} | |
enum:key,label,… | {{Status | enum:"o","Open","c","Closed"}} | |
number[:decimals | pattern] | {{Amount | number}}, {{Amount | number:"#,##0.0"}} | 1,234.50. With no argument: grouped, 2 decimals. |
currency[:code[,decimals]] | {{Total | currency:"EUR"}} | €1,234.50, or 1.234,50 € in de-DE. With no code, the culture's own currency. |
percent[:decimals] | {{Rate | percent:1}} | 0.456 becomes 45.6% |
round[:decimals], abs | {{Qty | round:2}} | |
add, sub, mul, div | {{Price | mul:Qty | round:2}} | Arguments may be other fields |
date[:pattern] | {{Due | date:"dd/MM/yyyy"}} | Patterns d/D/t/g/G are the culture's standard formats. Custom tokens: yyyy yy MMMM MMM MM M dddd ddd dd d HH H hh h mm ss tt. YYYY and DD work too. |
addDays, addMonths, addYears, addHours | {{Date | addDays:30 | date}} | |
startOf:unit, endOf:unit | {{Date | endOf:"month" | date}} | Units: day, week (starts Monday), month, quarter, year |
timezone:name | {{Created | timezone:"Asia/Kolkata" | date:"g"}} | |
count | {{Lines | count}} | Number of items (or characters, for text) |
sum, avg, min, max [:field] | {{Lines | sum:"Amount" | currency}} | |
first, last, reverse | {{Lines | first}} | |
map:field + join[:separator] | {{Lines | map:"Description" | join:", "}} | |
where:field,value or where:field,op,value | {{#each Lines | where:"Amount",">",1000}} | Operators: == != > >= < <= in contains |
sort[:field[,"desc"]], limit:n[,offset], distinct[:field] | {{#each Lines | sort:"Amount","desc" | limit:5}} | |
image[:width,height] | Alt text of a picture: {{Logo | image:"4cm"}} | The picture is replaced and its frame size kept (Office formats) |
Loops
{{#each Lines}}
{{@number}}. {{Description}} {{Amount | currency}}
{{else}}
No lines.
{{/each}}
- Inside a loop, names are read from the current item first, then from outer loops, then from the top level. So
{{Invoice.Currency}}still works inside{{#each Lines}}. {{#each Lines as line}}…{{line.Description}}…{{/each}}gives the item a name of its own.- Loop values:
{{@index}}: 0-based position.{{@number}}: 1-based position.{{@first}},{{@last}}: true on the first and last item.{{@count}}: number of items.{{@key}}: the key, when looping over an object.
{{@root.Field}}reads from the top level, even when a loop item has a field with the same name.
How much repeats in an office document: the smallest element that holds both {{#each}} and {{/each}}.
- Tags in the same table row repeat the row.
- Tags in different paragraphs repeat the paragraphs between them.
- Tags in one paragraph repeat just that text.
- A paragraph that holds nothing but a block tag is removed.
In text templates, a block tag on a line of its own takes that line with it.
Conditions
{{#if Invoice.Total > 100000 and Customer.Country == "IN"}}
High-value domestic invoice.
{{else if Invoice.Status in ["Draft", "Proforma"]}}
Not yet issued.
{{else}}
…
{{/if}}
{{#unless Invoice.Paid}}Payment due by {{Invoice.DueDate | date}}.{{/unless}}
- Operators:
==!=>>=<<=inandornot, plus parentheses. - Empty text,
0,false, empty lists and missing values count as false. - When both sides are numbers or dates, they are compared as numbers or dates.
Scope and variables
{{#with Customer}}{{Name}}, {{City}}{{/with}}
{{#set subtotal = Lines | sum:"Amount"}}Subtotal: {{subtotal | currency}}
Comments
{{! This never appears in the output }}
Format notes
- Word and PowerPoint:
- Line breaks in a value start a new line in Word.
- Blocks follow the rules under Loops. Put
{{#each}}and{{/each}}on their own paragraphs to repeat the paragraphs between them, or in two cells of one table row to repeat the row. {{else}}must be alone in its own paragraph.
- Pictures: put the tag in the picture's alt text (in Word or PowerPoint, Format Picture > Alt Text; in LibreOffice, the Description or Title), for example
{{Company.Logo}}.- The picture is replaced and keeps its size and position.
- The tag is removed from the alt text.
- Excel:
- A cell holding just one tag becomes a real number or date, so the cell's own number format applies.
- A block tag in one cell and its closing tag in a later row repeat those rows, and rows below move down.
- A block inside one cell repeats text within that cell.
- Row blocks can't be nested, and
{{else}}can't span rows. - Naming a range or a table after a child list repeats it too, without any block tags.
- OpenDocument:
- Extra spaces, line breaks and tabs in values are kept.
- In Calc, a cell holding one tag becomes a number or date cell.
- In Impress, a block repeats the frames between its tags.
- HTML and XML: values are escaped (
&becomes&, and so on). - JSON: a tag inside quotes is written as escaped string text. A tag standing alone is written as a JSON value: a number,
true/false,null, a list or an object. - Markdown and text: values are written as they are.