Skip to main content

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:

NameValue
{{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:"—"}}
FilterExampleResult
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: == != > >= < <= in and or not, 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 &amp;, 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.