Word Template Syntax
Word templates use a simple templating language and data sources to generate Word documents. Templates look like regular documents with embedded template expressions.
The example below shows the generated output from a word template and a data source:
Name: <<[Person.FirstName]>> <<[Person.LastName]>>Address:<<[Person.Address.Number]>>, <<[Person.Address.Street]>><<[Person.Address.City]>><<[Person.Address.Postcode]>>{ "Person": { "Title": "Mr", "FirstName": "John", "LastName": "Smith", "Address": { "Number": "5", "Street": "Saffron Road", "City": "Leicester", "Postcode": "LE18" } }}Name: John SmithAddress:5, Saffron RoadLeicesterLE18An expression is <<, some contents, followed by >>. When the template is executed, these expressions
are replaced with values from a data source.
Language features
Simple expressions
The following template defines two template expressions. If applied to the input object, the expressions will be replaced by the corresponding properties. The result is then:
<<[FirstName]>> <<[LastName]>>{ "FirstName": "Yehuda", "LastName": "Katz"}Yehuda KatzNested input objects
Sometimes, the input objects contain other objects or arrays. In such a case, you can use dot-notation to gain access to nested properties. For example:
<<[Person.FirstName]>> <<[Person.LastName]>>{ "Person": { "FirstName": "Yehuda", "LastName": "Katz" }}Yehuda KatzSome built-in helpers allow you to change the current context to a nested object. You can then access this object as if it were the root object.
Conditionals
You can use the if helper to conditionally render a block. If its argument returns false, undefined, null, "",
0, or [], the block will not be rendered.
A conditional expression must return a Boolean value (‘true’ or ‘false’). If none of the conditional expressions equate to true, and no fallback template is provided, the entire conditional block will be removed.
The first expression that returns true will trigger the corresponding template option to be used.
<<if [conditional_expression1]>>
template_option1
<<elseif [conditional_expression2]>>
template_option2
<<else>>
default_template_option
<</if>>For example
<<if [Author]>> <<[FirstName]>> <<[LastName]>><<else>> Unknown author<</if>>{ "Author": true, "FirstName": "Yehuda", "LastName": "Katz"}Yehuda KatzIf the input is an empty JSON object {}, then Author will become undefined and the if condition will fail, resulting in:
Unknown authorOperators
Build a Doc supports a number of operators to assist with template creation.
Operators are special symbols or keywords that tell the template engine how to manipulate values: whether it’s accessing data, performing mathematical operations, making decisions, or combining pieces of text. They are the “verbs” of your template expressions: they act on your data to produce the final output.
Primary Operators
Operators that let you access data and call functions. The expressions should be written using this syntax template: <<[x]>>
| Operator | Description | Example |
|---|---|---|
x.y | Access member/property y on object x. | person.Name → “Alice” |
x?.y | Safely access y on x; returns null if x is null. | user?.Email → null |
x.f() | Call helper or method f on variable x. | name.ToUpper() → “ALICE” |
a[x] | Retrieve element at index position x from array or list a. | colors[0] → “Red” |
a?[x] | Safely access item at index positon x in a; returns null if a is null. | items?[2] → null |
new T(...) | Create a new instance of type T with the given constructor arguments. | new DateTime(2025,1,1) → date obj |
Unary Operators
Operators that work on a single value. The expressions should be written using this syntax template: <<[-x]>>
| Operator | Description | Example |
|---|---|---|
-x | Negate a number: if amount is 5, then -amount yields -5; if total is -3, then -total yields 3 | -amount → -5 |
!x | Logical NOT: flips a boolean (true → false) | !isActive |
~x | Bitwise NOT: flips each single bit in the number - swaps all the 0s for 1s and all the 1s for 0s. Applies it to 0 (which is all zeros in binary) turns every bit into a 1, producing -1 | ~0 → -1 |
(T)x | Cast value x to type T | (int)3.14 → 3 |
Binary Operators
Arithmetic
Operators that perform basic mathematical calculations (addition, subtraction, multiplication, division, remainder). The expressions should be written using this syntax template: <<[x * y]>>
| Operator | Description | Example |
|---|---|---|
x * y | Multiply | 2 * 3 → 6 |
x / y | Divide | 6 / 2 → 3 |
x % y | Remainder | 7 % 4 → 3 |
x + y | Add numbers or concatenate strings | "A" + "B" → “AB” |
x - y | Subtract | 5 - 2 → 3 |
Bitwise
Operators that manipulate individual bits of integer values (shift, AND, OR, XOR, NOT). The expressions should be written using this syntax template: <<[x << y]>>
| Operator | Description | Example |
|---|---|---|
x << y | Shift bits of x left by y positions | 1 << 2 → 4 |
x >> y | Shift bits of x right by y positions | 4 >> 1 → 2 |
x & y | Bitwise AND | 3 & 1 → 1 |
x ^ y | Bitwise XOR | 5 ^ 3 → 6 |
x | y | Bitwise OR | 5 | 2 → 7 |
Relational
Operators that compare two values and return a boolean (true/false) result. The expressions should be written using this syntax template: <<[x < y]>>
| Operator | Description | Example |
|---|---|---|
x < y | True if x is less than y. | 2 < 3 → true |
x > y | True if x is greater than y. | 3 > 2 → true |
x <= y | True if x is ≤ y. | 2 <= 2 → true |
x >= y | True if x is ≥ y. | 3 >= 4 → false |
x == y | True if x equals y. | 5 == 5 → true |
x != y | True if x does not equal y. | 5 != 4 → true |
Logical
Operators that combine boolean values to form more complex conditions. The expressions should be written using this syntax template: <<[(x && y)]>>
| Operator | Description | Example |
|---|---|---|
x && y | True only if both x and y are true. | true && false → false |
x || y | True if either x or y is true. | true || false → true |
Null-Coalescing
Operators that provides a default when a value is null. The expressions should be written using this syntax template: <<[(x ?? y)]>>
| Operator | Description | Example |
|---|---|---|
x ?? y | Return x if not null; otherwise return y. | name ?? "Unknown" |
Loops
You can iterate over a list using the built-in foreach helper. Inside the block, you can use variable name to reference the
element being iterated over.
<<foreach [variable_name in sequence_expression]>>
data_band_body
<</foreach>>For example:
<<foreach [person in people]>> <<[person]>><</foreach>>Name: people
[ "Yehuda Katz", "Alan Johnson", "Charles Jolley"]Reference item position
When looping through items in a foreach statement, you can reference the position of each item using the IndexOf() and NumberOf() extension methods.
-
IndexOf()returns a zero‑based index (0 for the first item, 1 for the second, etc.). -
NumberOf()returns a one‑based index (1 for the first item, 2 for the second, etc.).
IndexOf() Example: Comma-Separated List
To manipulate the data source to turn it into a comma-separated list, the below method can be applied, utilising the IndexOf() method:
The fruits are:<<foreach [fruit in items]>> <<[ IndexOf() > 0 ? ", " : "" ]>><<[fruit]>><</foreach>>.Name: items
[ "Apple", "Banana", "Cherry"]The fruits are: Apple, Banana, Cherry.The example uses the foreach loop, applying the ternary rule ‘if the item’s index is greater than 0, add a comma before the item, else do nothing’ to each item from the data source.
-
First pass:
IndexOf() = 0 → no comma -
Later passes:
IndexOf() > 0 → insert ", "
This results in a comma-separated list, with a comma after each item except the first.
NumberOf() Example: Simple Numbered List
When looping through items in foreach, you can optionally reference the current loop index via the IndexOf() function.
You can use this function to distinguish sequence items with different indexes and then handle them in different ways. For example, given that items is a list of the strings “apples”, “bananas”, and “oranges”, you can use the following template to enumerate them, prefixing all but the first with commas. This is useful when producing lists.
No. - Item<<foreach [item in items]>> <<[ NumberOf() ]>> - <<[item]>><</foreach>>Name: items
[ "apples", "bananas", "oranges"]No. - Item1 - apples2 - bananas3 - orangesForce move to next Item
You can instruct the engine to force movement to the next item within a loop using a next tag.
This feature is useful in label-print-like scenarios when you need to output data about a fixed number of items in a single table row, like in the following example.
Given that Clients is a list having a field named “Name”, you can use the following template to output three client names per row while outputting names of all clients. The next tag forces an increment in the loop, ‘jumping’ to the next item and allowing access to it before the next pass of the loop. As this moves the count of the loop on one place, the next pass of the loop will continue from the next sequential position.
In this case, the engine produces a document as follows:
<<foreach [c in Clients]>><<[c.Name]>><<next>><<[c.Name]>><<next>><<[c.Name]>><</foreach>>Name: Clients
[ { "Name": "A Company" }, { "Name": "B Ltd." }, { "Name": "C & D" }, { "Name": "E Corp." }, { "Name": "F & Partners" }, { "Name": "G & Co." }, { "Name": "H Group" }, { "Name": "I & Sons" }, { "Name": "J Ent." }]| A Company | B Ltd. | C & D |
|---|---|---|
| E Corp. | F & Partners | G & Co. |
| H Group | I & Sons | J Ent. |
Formatting values
Expression tags let you control how raw data appears in your document - whether as dates, numbers, or styled text. You insert a format directive directly into your placeholder, and the engine applies it at run time.
You can format values using expression tags. An expression tag serves as a placeholder for an expression result within a template, and allows you to specify a format for the output.
An expression tag has no name and consists of the following elements:
- An expression enclosed by brackets
- An optional format string enclosed by double quotes and preceded by the ”:” character
- An optional html switch
<<[expression]:"format" -html>>Format string
The format string can be used to format numeric values or strings, and must correspond to the expected format described in the context provided: a string method can only be applied to a string, and a dateTime method can only be applied to a dateTime etc.
If you have a string or numeric value and you want to format it into a specific pattern, you can do so by using the format string within the expression tag. In the below example, the string is formatted to upper case.
<<[string]:upper>>welcomeMessage: = Hello, World!
<<[welcomeMessage]:upper>>HELLO, WORLD!HTML Switch
Values can be formatted using an optional HTML switch when outputting expression results. This allows you to insert HTML content dynamically into your reports while maintaining the formatting of the template document.
When using an expression tag, you can include the HTML switch to treat the expression result as an HTML block.
You can use the following syntax for an expression tag with a HTML switch:
<<[htmlString] -html>><<["<b>Bold</b> and <i>italic</i> text"] -html>>Bold and italic text
Dates and Times
Dates from an data source property can be formatted using the following syntax.
<<[expression]:"pattern">>For example:
<<[person.DateOfBirth]:"dd/MM/yyyy">>{ "Person": { "DateOfBirth": "1981-09-24" }}24/09/1981
Numbers
Provides several additional number formats that can not be specified using format strings. The following table describes these formats.
| Number Format | Description |
|---|---|
| alphabetic | Formats an integer number as an upper-case letter (A, B, C, …) |
| roman | Formats an integer number as an upper-case Roman numeral (I, II, III, …) |
| ordinal | Appends an ordinal suffix to an integer number (1st, 2nd, 3rd, …) |
| ordinalText | Converts an integer number to its ordinal text representation (First, Second, Third, …) |
| cardinal | Converts an integer number to its text representation (One, Two, Three, …) |
| hex | Formats an integer number as hexadecimal (8, 9, A, B, C, D, E, F, 10, 11, …) |
| arabicDash | Encloses an integer number with dashes (- 1 -, - 2 -, - 3 -, …) |
The following is an example of how you can use one of these additional number formats, instead of a format string. Given that i is an integer number, you can format i as an upper-case letter (1 = A, 2 = B, 3 = C, …).
<<[i]:alphabetic>>"i": 3 C
Strings
The following table describes these formats.
| String Format | Description |
|---|---|
| lower | Converts a string to lower case (“the string”) |
| upper | Converts a string to upper case (“THE STRING”) |
| caps | Capitalises a first letter of every word in a string (“The String”) |
| firstCap | Capitalises the first letter of the first word in a string (“The string”) |
The following is an example of how you can specify an additional string format. Given that s is a string, you can capitalise the first letter of every word in s using the following template.
<<[s]:caps>>{ "s": "hello, world!"}Hello, World!
Combine formatters
You can also combine expression formatters like in the following examples. Given that d is a DateTime value, you can convert its textual month representation to upper case using the following template.
<<[d]:"MMMM":upper>>{ "d": "2021-09-24T00:00:00"}SEPTEMBER
<<[i]:roman:lower>>{ "i": 7}vii
Using Variables
Templates enable you to use variables in template documents. Use variables to store expensive calculations once and reuse the result throughout your template. This is particularly useful for complex calculations, such as running totals.
You can declare a variable in a template using a var tag:
<<var [variable_type variable_name = variable_value]>>If you do not specify the type explicitly, it is determined implicitly from the specified variable value.
Each new variable must have a unique identifier. After a variable is declared in a template, its value can be accessed using its name, just like any other variable.
<<var [s = "Hello!"]>><<[s]>>Hello!
You can redefine the value of a variable using a var tag against the name of this variable. For example, the following template outputs string “Hello, World!”
<<var [s = "Hello, "]>><<[s]>><<var [s = "World!"]>><<[s]>>Hello, World!
Variables come with the following restrictions:
- You can not redefine the type of a variable.
- Using a var tag, you can not redefine the value of an iteration variable or a data source.
External Documents
You can insert contents from other documents into your document dynamically using doc tag. A doc tag denotes a placeholder within a template for a document to be inserted.
Syntax of a doc tag is defined as follows.
<<doc [document_expression]>>An expression declared within a doc tag must return a base64 encoded document.
By default, a document being inserted is not checked against template syntax and is not populated with data. However, you can enable this by using a build switch:
<<doc [document_expression] -build>>When you use a build switch, the template will treat the inserted document like its own mini-template, and so long as it is available at the scope of a corresponding doc tag, it can use:
-
Any data sources you’ve set up
-
Any variables you’ve defined
Report Title: <<[ReportTitle]>>
<<doc [CustomerInfoDocument] -build>>
Summary:<<[Summary]>>Customer Information--------------------Name: <<[Customer.Name]>>Email: <<[Customer.Email]>>Joined: <<[Customer.JoinDate]>>{ "ReportTitle": "Quarterly Report Q3", "Summary": "All metrics are on track.", "Customer": { "Name": "Acme Corp", "Email": "contact@acme.example.com", "JoinDate": "2022-01-15" }, "CustomerInfoDocument": "<BASE64_ENCODED_CONTENT_OF_CustomerInfo.docx>"}Report Title: Quarterly Report Q3
Customer Information--------------------Name: Acme CorpEmail: contact@acme.example.comJoined: 2022-01-15
Summary:All metrics are on track.Images
You can insert images into your document dynamically using an image tag, via the following steps:
-
Add a Textbox: Place a textbox in your template where you want the image to be inserted.
-
Set Image Attributes: Configure common image attributes for the textbox, such as frame and size, so that it visually appears as a blank image placeholder.
-
Specify an Image Tag: Within the textbox, use the following syntax to declare an image tag:
<<image [image_template_expression]>>
The template expression must return a value of one of the following types:
- Base64 encoded
- String containing an image URI

Name: logo
{ "url": "https://buildadoc.com/logo_example.svg"}
By default, the engine stretches an image filling a textbox to the size of the textbox. However, you can change this behavior in the following ways:
-
To keep the width of the textbox and change its height preserving the ratio of the image, use the
fitHeightswitch as follows.<<image [image_expression] -fitHeight>> -
To keep the height of the textbox and change its width preserving the ratio of the image, use the
fitWidthswitch as follows.<<image [image_expression] -fitWidth>> -
To change the size of the textbox according to the size of the image, use the
fitSizeswitch as follows.<<image [image_expression] -fitSize>> -
To change the size of the textbox according to the size of the image without increasing the size of the textbox, use the
fitSizeLimswitch as follows.<<image [image_expression] -fitSizeLim>>
Links
You can insert hyperlinks into your spreadsheets using link tags. Syntax of a link tag is defined as follows.
<<link [uri_or_bookmark_template_expression][display_text_template_expression]>>Here, uri_or_bookmark_template_expression defines a URI or the name of a bookmark within the same document for a hyperlink to be inserted dynamically. This expression is mandatory and must return a non-empty value.
In turn, display_text_template_expression defines text to be displayed for the hyperlink. This expression is optional. If it is omitted or returns an empty value, then during runtime, a value of uri_or_bookmark_template_expression is used as display text as well.
<<link [uri][display text]>>{ "url": "https://help.buildadoc.com/", "name": "Build a Doc"}
</TabItem>
<TabItem label="Output">
<a href="https://help.buildadoc.com/" target="_blank">Build a Doc</a> </TabItem></Tabs>
<Aside> Values of both `uri_or_bookmark_template_expression` and `display_text_template_expression` can be of any type.</Aside>
While building a document, `uri_or_bookmark_template_expression` and `display_text_template_expression` are evaluated and their results are used to construct a hyperlink that replaces the corresponding `link` tag. If `uri_or_bookmark_template_expression` returns the name of a bookmark in the same document, then the hyperlink navigates to the bookmark. Otherwise, the hyperlink navigates to a corresponding external resource.
## Text Colour
You can set a font colour for text contents dynamically using `textColor` tags. Syntax of a `textColor` tag is defined as follows.
<Tabs> <TabItem label="Template"> ```lua <<textColor [color]>> <<[content]>> <</textColor>><<textColor ["#FF0000"]>><<[This text will be red.]>><</textColor>>This text will be red.
The expression color_expression must return a value of one of the following types:
-
A string containing the name of a known colour, that is, the case-insensitive name of a member of the KnownColor enumeration:
<<textColor [“red”]>>text with red font<</textColor>> -
A string containing an HTML colour code:
<<textColor [“#F08080”]>>text with light coral font<</textColor>> -
An integer value defining RGB (red, green, blue) components of the colour:
<<textColor [0xFFFF00]>>text with yellow font<</textColor>>
You can use textColor tags nested into each other, and can typically use textColor tags within tables and conditional blocks.
Background Colour
You can set text background colour for document contents dynamically using backColor tags. Syntax of a backColor tag is defined as follows.
<<backColor [color_expression]>>content_to_be_coloured<</backColor>><<["#FFFF00"]>><<["This text has a yellow background."]>>This text has a yellow background.
An expression declared within an opening backColor tag defines a text background colour to be applied during build. The expression must return a value of one of the following types:
-
A string containing the name of a known colour, that is, the case-insensitive name of a member of the KnownColor enumeration like in the following example.
<<backColor [“red”]>>text with red background<</backColor>> -
An integer value defining RGB (red, green, blue) components of the colour like in the following example.
<<backColor [0xFFFF00]>>text with yellow background<</backColor>> -
A value of the Color type.
You can nest backColor tags to layer multiple background effects. You can also place backColor tags inside data bands and conditional blocks—for example, to wrap each item in its own paragraph whose background colour is set dynamically.
<<foreach [item in items]>><<backColor [item.Color]>><<[item.Name]>><</backColor>><</foreach>>You can also use a backColor tag to dynamically apply a solid fill colour to a shape by following these steps:
-
Add the shape to your template.
-
Set the shape’s fill option to “No fill.”
-
In the shape’s textbox, insert opening and closing
backColortags so they wrap around all the text inside the box (if any), like in the example below.<<backColor [“red”]>>text inside shape<</backColor>>
Lists
Within a list, you can dynamically reset numbering back to 1 using the restartNum tag. This feature is particularly useful when working with a nested numbered list within a data band, as shown in the example below.
By placing a restartNum tag before the corresponding foreach tag in your template, you can ensure that the list numbering restarts for each item.
When used in a list, the restartNum tag will reset the numbering.
<<foreach [order in orders]>><<[order.ClientName]>> (<<[order.ClientAddress]>>) <<restartNum>> 1. <<foreach [service in order.Services]>> <<[service.Name]>> <</foreach>><</foreach>>{ "orders": [ { "ClientName": "Acme Corp", "ClientAddress": "123 Main St", "Services": [ { "Name": "Consulting" }, { "Name": "Implementation" } ] }, { "ClientName": "Globex Inc", "ClientAddress": "456 Elm Rd", "Services": [ { "Name": "Support" }, { "Name": "Training" }, { "Name": "Maintenance" } ] } ]}Acme Corp (123 Main St)
- Consulting
- Implementation
Globex Inc (456 Elm Rd)
- Support
- Training
- Maintenance
Tables
You can dynamically populate tables using Build a Doc template expressions.
A table‑row body can span one or more rows of a document table. Its band begins at the start of the first occupied row and ends at the close of the last occupied row:
<<foreach ...>>… | … | … |
| … | … | … |
| … | … | … <</foreach>> |
For example, to populate a document table given the data source.
| Client | Manager | Contract Price |
|---|---|---|
<<foreach [c in Contracts]>><<[c.Clients.Name]>> | <<[c.Managers.Name]>> | <<[c.Price]>><</foreach>> |
| Total: | <<[Contracts.Sum(c=>c.Price)]>> |
Name: Contracts
Data:
[ { "Clients": { "Name": "A Company" }, "Managers": { "Name": "John Smith" }, "Price": 1200000 }, { "Clients": { "Name": "B Ltd." }, "Managers": { "Name": "John Smith" }, "Price": 750000 }, { "Clients": { "Name": "C & D" }, "Managers": { "Name": "John Smith" }, "Price": 350000 }, { "Clients": { "Name": "E Corp." }, "Managers": { "Name": "Tony Anderson" }, "Price": 650000 }]| Client | Manager | Contract Price |
|---|---|---|
| A Company | John Smith | 1200000 |
| B Ltd. | John Smith | 750000 |
| C & D | John Smith | 350000 |
| E Corp. | Tony Anderson | 650000 |
| Total: | 2950000 |
| Manager/Client | Contract Price |
|---|---|
<<foreach [m in Managers]>><<[m.Name]>> | <<[Contracts.Where(c => c.ManagerID==m.ID).Sum(c => c.Price)]>> |
<<foreach [c in Contracts.Where(c => c.ManagerID==m.ID)]» «[c.Clients.Name]>> | <<[c.Price]>><</foreach>><</foreach>> |
| Total: | <<[Contracts.Sum(c=>c.Price)]>> |
Name: Contracts
Data:
[ { "Clients": { "Name": "A Company" }, "ManagerID": 1, "Price": 1200000 }, { "Clients": { "Name": "B Ltd." }, "ManagerID": 1, "Price": 750000 }, { "Clients": { "Name": "C & D" }, "ManagerID": 1, "Price": 350000 }, { "Clients": { "Name": "E Corp." }, "ManagerID": 2, "Price": 650000 }]Name: Managers
Data:
[ { "ManagerID": 1, "Name": "John Smith" }, { "ManagerID": 2, "Name": "Tony Anderson" }]| Manager/Client | Contract Price |
|---|---|
| John Smith | 2300000 |
| A Company | 1200000 |
| B Ltd. | 750000 |
| C & D | 350000 |
| Tony Anderson | 650000 |
| E Corp. | 650000 |
| Total: | 2950000 |
| Manager | Clients |
|---|---|
<<foreach [m in Managers]>><<[m.Name]>> | <<foreach [c in m.Contracts]>><<[c.Clients.Name]>><</foreach>><</foreach>> |
Name: Managers
Data:
[ { "ManagerID": 1, "Name": "John Smith", "Contracts": [ { "Clients": { "Name": "A Company" }, "Price": 1200000 }, { "Clients": { "Name": "B Ltd." }, "Price": 750000 }, { "Clients": { "Name": "C & D" }, "Price": 350000 } ] }, { "ManagerID": 2, "Name": "Tony Anderson", "Contracts": [ { "Clients": { "Name": "E Corp." }, "Price": 650000 } ] }]| Manager | Clients |
|---|---|
| John Smith | A Company B Ltd. C & D |
| Tony Anderson | E Corp. |
Single Column Tables
Single‑column tables are treated differently: when the opening and closing foreach tags are both placed in the same cell, the engine treats that band as a standard data band rather than a table‑row band by default. This displays the content as a basic block of repeated content, similar to a single line of text, rather than as a table row band, which spreads the content across multiple rows. The examples below demonstrate this behaviour.
Example 1: Table-Row Band
Managers Table (Table-Row Band)
| Name |
|---|
<<foreach [m in Managers]>> |
<<[m.Name]>> |
<</foreach>> |
{ "Managers": [ { "Name": "John Smith" }, { "Name": "Tony Anderson" }, { "Name": "July James" } ]}Managers Table (Table-Row Band)
| Name |
|---|
| John Smith |
| Tony Anderson |
| July James |
Example 2: Standard Data Band:
Managers List (Standard Data Band)
| Managers |
|---|
<<foreach [m in Managers]>><<[m.Name]>> <</foreach>> |
{ "Managers": [ { "Name": "John Smith" }, { "Name": "Tony Anderson" }, { "Name": "July James" } ]}Managers List (Standard Data Band)
| Managers |
|---|
| John Smith Tony Anderson July James |
-greedy Switch
The -greedy switch is used to influence how tags are processed, particularly when using nested tags.
When the -greedy switch is applied to a tag, the engine captures as much content as possible for that tag, including any nested tags. This can be particularly useful if you need to ensure that all relevant data is included, even if there are multiple nested instances of the same tag type; the -greedy switch will help ensure that all iterations of the inner tag are captured effectively without being prematurely terminated by the outer tag.
<<foreach [items] -greedy>>Item: <<[Name]>><<foreach [subItems]>>Sub-item: <<[SubItemName]>><</foreach>><</foreach>>Name: items
{ "items": [ { "Name": "Fruit", "subItems": [ { "SubItemName": "Apple" }, { "SubItemName": "Banana" } ] }, { "Name": "Vegetable", "subItems": [ { "SubItemName": "Carrot" }, { "SubItemName": "Lettuce" } ] } ]}Item: FruitSub-item: AppleSub-item: BananaItem: VegetableSub-item: CarrotSub-item: LettuceMerging Cells
You can dynamically merge table cells with the same textual contents using cellMerge tags.
<<cellMerge -horz>>
A horizontal switch is optional. If the switch is present, it denotes a cell merging operation in a horizontal direction. If the switch is missing, it means that a cell merging operation is to be performed in a vertical direction (the default).
For two or more successive table cells to be merged, in either direction, the following requirements must be met:
- Each of the cells must contain a
cellMergetag, indicating a cell merging operation in the same direction. - Each of the cells must not be already merged in another direction.
- The cells must have equal textual contents (ignoring leading and trailing whitespaces).
Consider the following template.
...<<cellMerge>><<[value1]>>...<<cellMerge>><<[value2]>>If value1 and value2 have the same value, say “Hello”, table cells containing cellMerge tags are successfully merged during runtime:
...Hello...If value1 and value2 have different values, say “Hello” and “World”, table cells containing cellMerge tags are not merged during runtime:
...Hello...WorldCharts
You can create and manipulate different types of dynamically populated charts by following these steps:
- Add a Chart to Your Template: Place a chart in your template at the desired location in the document.
- Configure your Chart Appearance: Set up the visual aspects of the chart as needed.
- Use
foreachTags: To populate the chart with dynamic data, include aforeachtag in the chart title. This allows the charts to iterate over a data collection. - Add Chart Series: Define the chart series and configure their appearance. This can be done by right clicking on the chart, and selecting ‘Edit Data’. Update the Series Name by adding a template expression into the Series Name. This will populate that series with data from the data source at runtime.
- Define X and Y Values: us
X, Y, sizeand other relevant tags to specify expressions that pull data for the chart series. For example:
-
<<x [x_value_expression]>>for x-values. X values must be declared in the Chart Title, just after the<<foreach>>opening tag. -
<<y [y_value_expression]>>for y-values. Y values must be declared in Series Titles. -
The expressions must return appropriate data types as per the chart requirements.
-
If you want to conditionally include or exclude chart series based on certain criteria, you can use the
removeiftag to specify conditions under which series should not be displayed.
An example of a pie chart before data has been inserted:

Name = managers
[ { "Value": 600, "Name": "John Smith" }, { "Value": 200, "Name": "Alice Taylor" }, { "Value": 300, "Name": "Robert Quill" }, { "Value": 400, "Name": "Isaac Thompson" }]An example of the resulting Pie Chart after runtime:

- Colours can be set dynamically using
seriesColororpointColortags, allowing for customised data.
Chart Title: <<chartTitle>>
<<foreach [managers]>> Series Name: <<seriesName [Name]>> <<seriesColor [Color]>> <<y [Contracts.Sum(Price)]>><<removeif [some_condition]>><<endforeach>>Here’s an example of how the tags might look in your template:
Chart Title: <<chartTitle>>
<<foreach [managers]>> Series Name: <<seriesName [Name]>> <<seriesColor ["#FF5733"]>> <<seriesColor ["#33C3FF"]>> <<y [Contracts.Sum(Price)]>><</foreach>>{ "chartTitle": "Contracts by Manager", "managers": [ { "Name": "Alice", "Contracts": [ { "Price": 100 }, { "Price": 200 } ] }, { "Name": "Bob", "Contracts": [ { "Price": 150 }, { "Price": 50 } ] } ]}
In this example:
<<chartTitle>>sets the dynamic title of the chart.<<seriesName [Name]>>sets the name of each series based on the manager’s name.<<seriesColor [Color]>>assigns a colour to each series.<<y [Contracts.Sum(Price)]>>specifies the y-value for the series.
By following these steps and using the appropriate tags, you can configure the chart appearance in your report.