Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents
minLevel1
maxLevel3
outlinefalse
styledefault
typelist
printabletrue

Word Template Reference v2

Basic Usage

IdealDoc expressions are some contents enclosed by double curly braces {{}}. In the below template, firstname is a variable that is enclosed by double curly braces, which is said to be an expression.template

Code Block
{{firstname}} {{lastname}}

If the below input object is applied to the templateinput

Code Block
{
  firstname: "Yehuda",
  lastname: "Katz",
}

Expressions are compiled to produce the output as follows:output

Code Block
Yehuda Katz

Path expressions

IdealDoc expressions can also be dot-separated paths.template

Code Block
{{person.firstname}} {{person.lastname}}

This expression looks up the person property in the input object and in turn looks up the firstname and lastname property within the person object.

Pass the below input object to the template:nput

Code Block
{
  person: {
    firstname: "Yehuda",
    lastname: "Katz",
  },
}

Output will be generated as below:output

Code Block
Yehuda Katz

Changing the context

Some helpers like #with and #each allow you to dive into nested objects. When you include ../ segments in your path, IdealDoc will change back into the parent context.template

Code Block
{{#each people}}
    {{../prefix}} {{firstname}} 
{{/each}}

Even though the name is printed while in the context of a comment, it can still go back to the main context (the root-object) to retrieve the prefix.

WARNING

The exact value that ../ will resolve to varies based on the helper that is calling the block. Using ../ is only necessary when context changes. Children of helpers such as {{#each}} would require the use of ../ while children of helpers such as {{#if}} do not.

Code Block
{{permalink}}
{{#each comments}}
  {{../permalink}}

  {{#if title}}
    {{../permalink}}
  {{/if}}
{{/each}}

In this example all of the above reference the same prefix value even though they are located within different blocks. IdealDoc also allows for name conflict resolution between helpers and data fields via a this reference:

Literal segments

Identifiers may be any unicode character except for the following:

Whitespace ! " # % & ' ( ) * + , . / ; < = > @ [ \ ] ^ ` { | } ~

In addition, the words true, false, null and undefined are only allowed in the first part of a path expression.

To reference a property that is not a valid identifier, you can use segment-literal notation, [. You may not include a closing ] in a path-literal, but all other characters are allowed.

JavaScript-style strings, " and ', may also be used instead of [ pairs.template

Code Block
{{!-- wrong: {{array.0.item}} --}}
correct: array.[0].item: {{array.[0].item}}

{{!-- wrong: {{array.[0].item-class}} --}}
correct: array.[0].[item-class]: {{array.[0].[item-class]}}

{{!-- wrong: {{./true}}--}}
correct: ./[true]: {{./[true]}}

HTML-escaping

In IdealDoc, the values returned by the {{expression}} are HTML-escaped. Say, if the expression contains &, then the returned HTML-escaped output is generated as &amp;. If you don't want IdealDoc to escape a value, use the "triple-stash", {{{:

In the below template, you can learn how to produce the HTML escaped and raw output.template

Code Block
raw: {{{specialChars}}}
html-escaped: {{specialChars}}

Pass the special characters to the templateinput

Code Block
{ specialChars: "& < > \" ' ` =" }

Expressions enclosed by "triple-stash" ({{{) produce the raw output. Otherwise, HTML-escaped output is generated as below.

output

Code Block
raw: & < > " ' ` =
html-escaped: &amp; &lt; &gt; &quot; &#x27; &#x60; &#x3D;

Subexpressions

IdealDoc offers support for subexpressions, which allows you to invoke multiple helpers within a single directive, and pass in the results of inner helper invocations as arguments to outer helpers. Subexpressions are delimited by parentheses.

Code Block
{{outer-helper (inner-helper 'abc') 'def'}}

In this case, inner-helper will get invoked with the string argument 'abc', and whatever the inner-helper function returns will get passed in as the first argument to outer-helper (and 'def' will get passed in as the second argument to outer-helper).

Whitespace Control

Template whitespace may be omitted from either side of any directive statement by adding a ~ character by the braces. When applied all whitespace on that side will be removed up to the first IdealDoc expression or non-whitespace character on that side.

Code Block
{{~title}}

Escaping expressions

Expression content may be escaped in one of two ways, inline escapes or raw block helpers. Inline escapes created by prefixing a block with \. Raw blocks are created using {{{{ braces.

Code Block
\{{escaped}}
{{{{raw}}}}
  {{escaped}}
{{{{/raw}}}}

Raw blocks operate in the same manner as other block helpers with the distinction of the child content is treated as a literal string.

Helper Functions

Functions or Helpers provide additional functionality to the template.

Literal arguments

Helper calls may also have literal values passed to them either as parameter arguments or hash arguments. Supported literals include numbers, strings, true, false, null and undefined. Strings always need to be enclosed in quotes “my string” while numbers, booleans and null or undefined are passed without quotes.te

Disambiguating helpers calls and property lookup

If a helper is registered by the same name as a property of an input object, the helper has priority over the input property. If you want to resolve the input property instead, you can prefix its name with ./ or this.

Block Helpers

Block helpers are built in functions which operate on a whole block of text. A Block is defined by a starting directive #<directive name> and an ending directive /<directive name>. The most common block functions are used for loops (each) and conditions (if).

Context switch (#with)

The with-helper allows you to change the evaluation context of template-part.template

Code Block
{{#with person}}
{{firstname}} {{lastname}}
{{/with}}

when used with this context:input

Code Block
{
  person: {
    firstname: "Yehuda",
    lastname: "Katz",
  },
}

will result in:output

Code Block
Yehuda Katz

with can also be used with block parameters to define known references in the current block. The example above can be converted toe

Code Block
{{#with city as | city |}}
  {{#with city.location as | loc |}}
    {{city.name}}: {{loc.north}} {{loc.east}}
  {{/with}}
{{/with}}

Which allows for complex templates to potentially provide clearer code than ../ depthed references allow for.

You can optionally provide an {{else}} section which will display only when the passed value is empty.template

Code Block
{{#with city}}
{{city.name}} (not shown because there is no city)
{{else}}
No city found
{{/with}}

input

Code Block
{
  person: {
    firstname: "Yehuda",
    lastname: "Katz",
  },
}

Iterators (#each)

You can iterate over a list using the built-in each helper. Inside the block, you can use this to reference the element being iterated over.template

Code Block
{{#each people}}
{{this}}
{{/each}}

when used with this context:input

Code Block
{
  people: [
    "Yehuda Katz",
    "Alan Johnson",
    "Charles Jolley",
  ],
}

will result in:output

Code Block
Yehuda Katz
Alan Johnson
Charles Jolley

You can use the this expression in any context to reference the current context.

You can optionally provide an else section which will display only when the list is empty.template

Code Block
{{#each paragraphs}}
{{this}}
{{else}}
No content
{{/each}}

When looping through items in each, you can optionally reference the current loop index via {{@index}}.

Code Block
{{#each array}} {{@index}}: {{this}} {{/each}}

Additionally for object iteration, {{@key}} references the current key name:

Code Block
{{#each object}} {{@key}}: {{this}} {{/each}}

The first and last steps of iteration are noted via the @first and @last variables when iterating over an array.

Nested each blocks may access the iteration variables via depth based paths. To access the parent index, for example, {{@../index}} can be used.

Conditionals (if / unless)

if condition

You can use the if helper to conditionally render a block. If its argument returns false, undefined, null, "", 0, or [], IdealDoc will not render the block.

template

Code Block
{{#if author}}
{{firstName}} {{lastName}}
{{/if}}

When you pass the following input to the above template

Code Block
{
  author: true,
  firstName: "Yehuda",
  lastName: "Katz",
}

This will produce the result as below:output

Code Block
Yehuda Katz

If the input is an empty JSONObject {}, then author will become undefined and if condition fails, resulting in an empty output

When using a block expression, you can specify a template section to run if the expression returns a falsy value. The section, marked by else is called an "else section".template

Code Block
{{#if author}}
{{firstName}} {{lastName}}
{{else}}
Unknown Author
{{/if}}

includeZero:

The includeZero=true option may be set to treat the conditional as not empty. This effectively determines if 0 is handled by the positive or negative path.

Code Block
{{#if 0 includeZero=true}}
Does render
{{/if}}

Conditionals may also be chained by including the subsequent helper call within the else directive.

Code Block
{{#if isActive}}
  show if isActive is true
{{else if isInactive}}
  show if isInactive true
{{/if}}

It is not necessary to use the same helper in subsequent calls, the unless helper could be used in the else portion as with any other helper. When the helper values are different, the closing directive should match the opening helper name.

unless (= if not) condition

You can use the unless helper as the inverse of the if helper. Its block will be rendered if the expression returns a falsy value.template

Code Block
{{#unless license}}
WARNING: This entry does not have a license!
{{/unless}}

If looking up license under the current context returns a falsy value, IdealDoc will render the warning. Otherwise, it will render nothing

compare

Syntax

Code Block
{{compare param1 operator param2}}

param1 and param2 are the parameters to be compared. They can be either static string values enclosed in quotes (e.g. compare “2” “>” “1”) or dynamic variables (e.g. a “>” b).

The operator is a string argument enclosed in quotes defining one of the following operators to be applied:

equals: “==” or “===”
not equals: “!=” or “!==”
less than: “<“
less or equal: “<=”
greater than: “>”
greater or equal: “>=”

compare can be used as block or inline expression.

Block Expression:te

Code Block
{{#compare a ">" b}}
shown if a greater than b
{{else}}
(optional) if an invers (else) expression is provided
{{/compare}}

As single expression:

Code Block
{{#if (compare a ">" b)}}
shown if a greater than b
{{else}}
(optional) if an invers (else) expression is provided
{{/if}}

contains

Block helper that renders the block if collection has the given value, using strict equality (===) for comparison, otherwise the inverse block is rendered (if specified). If a startIndex is specified and is negative, it is used as the offset from the end of the collection.

Example input:

Code Block
{
  myArray: ['a', 'b', 'c']
}

Example template:

Code Block
{{#contains myArray "c" startIndex=-1}}
This will not be rendered.
{{else}}
This will be rendered.
{{/contains}}

concat

Helper which concatenates several strings into one.

Example input:

Code Block
{
  myString: 'Hello'
}

Example template:

Code Block
{{concat myString " " "World!"}} --> results in "Hello World!"

lookup

The lookup helper allows for dynamic parameter resolution using IdealDoc variables. This can be useful for resolving values for array indexes.

Code Block
{{#each people}}
{{.}} lives in {{lookup ../cities @index}} 
{{/each}}

It can also be used to lookup properties of object based on data from the input.The lookup helper allows for dynamic parameter resolution using variables.

It can also be used to lookup properties of object based on data from the input.

Example input:

Code Block
{
  "lang": "en", --> will be queried dynamically from a field etc.
  "statusPicklistValue": "open", --> will be queried dynamically from a field etc.
  "Labels.de.open": "Offen",
  "Labels.de.closed": "Geschlossen",
  "Labels.en.open": "Open",
  "Labels.en.closed": "Closed",
  "Labels.de.status.open": "Offen",
  "Labels.de.status.closed": "Geschlossen",
  "Labels.en.status.open": "Open",
  "Labels.en.status.closed": "Closed",
  "Labels.open_de": "Offen",
  "Labels.closed_de": "Geschlossen",
  "Labels.open_en": "Open",
  "Labels.closed_en": "Closed",
}

Example template:

Code Block
{{@p#with (lookup Labels lang)~}}
Text: {{lookup status @root.statusPicklistValue}}
{{@p/with}}
Or:
{{lookup (lookup Labels lang) statusPicklistValue}}
Or (with concat):
{{lookup Labels (concat statusPicklistValue "_" lang)}}

empty

Inline helper to evaluate whether a given String or an Array or an Object is empty or null/undefined.

Example input:

Code Block
{
  emptyArray: [],
  emptyString: '',
  emptyObject: {}
}

Example template:

Code Block
{{#if (empty emptyArray}}
Array is empty.
{{else}}
Array is not empty.
{{/contains}}

logic (and / or / no)

and

Helper that renders the block if all of the given values are truthy. If an inverse block is specified it will be rendered when falsy. Works as a block helper, inline helper or subexpression. In the following example t1,t2 variables are true and f1 is false.

Block expression:

Code Block
{{#and t1 t2 t3}}
will be rendered
{{else}}
(optional): will be shown when and is false
{{/and}}

Subexpression:

Code Block
{{#if (and t1 t2 f1)}}
will not be rendered (because f1 is false)
{{/if}}

or

Helper that renders a block if any of the given values is truthy. If an inverse block is specified it will be rendered when falsy. Works as a block helper, inline helper or subexpression. In the following example t1 variable is true and f1, f2 are false.

Block expression:

Code Block
{{#or f1 f2 t1}}
will be rendered
{{else}}
(optional): will be shown when or is false
{{/or}}

Subexpression:

Code Block
{{#if or(f1 f2 t1)}}
will be rendered
{{else}}
(optional): will be shown when or is false
{{/or}}

not

Returns the inverse boolean of the provided value. I.e. it returns false when the provided expression is true and vica versa. Works as block expression or inline expression:

Block expression:te

Code Block
{{#not t1}}
Not rendered
{{/not}}

Inline expression:te

Code Block
{{#if (not (compare a ">" b))}}
Shown if a is less or equal than b
{{/not}}

image

Images can be dynamically rendered using the {{image function. The image data can either be fetched from a public url with the url=… attribute or by passing directly some base64 encoded image data ( data=…). The attribute values can be passed either as static values or from a variable in the current context.

The width and height of an image can be specified (in cm). If only one dimension is specified the other dimension is automatically calculated retaining the correct aspect ratio.

With the alt= attribute an alternative text can be specified which gets displayed in case an image could not be rendered.

With the caption= attribute an image caption can be defined.te

Code Block
{{image url="https://my-static-image-url" width="5" height="3" alt="" caption=""}}
{{image data=base64ImgData}}

html (Rich Text)

By using the html function, a html snippet will be converted to the docx format. This is useful for dynamically including for example richt text fields in HTML format in the docx.te

Code Block
{{html content=htmlContentVariable}}

lineBreak

With the lineBreak function non html text fields containing line breaks (/n) will be displayed as multiline output in the resulting document. Example:

Code Block
{{lineBreak "multi/nline/ntext field"}}

results in:

Code Block
multi
line
text field

With the link function native Word links can be created.te

Code Block
{{link url=urlVariable label="Optional Link Label"}}
{{link url="https://mystaticurl.com"}

Date / Date Time Fields

Formatting date or date and time strings is supported through a built in $date() function.

{{date <date/time string> [format=pattern]}}

The shortcut function today can be used to display the current date or date time.

{{today [format=pattern]}}

The provided date/time string needs to be in ISO 8601 format. For example:

‘2018-04-04T16:00:00.000Z'
'2018-04-13 19:18:17.040+02:00'
'2018-04-13 19:18'
'2018-04-13’

The format pattern is optional and needs to follow the date formatting specification described here. If no format pattern is provided the format pattern from the provided json configuration or the default pattern will be used. for example:

{{date createdDate}}

{{dateTime createdDateTime}}

{{dateTime createdDateTime format="D.M.YYYY hh:mm:ss"}}

{{today format="D.M.YYYY hh:mm:ss"}}

Number Fields

Formatting numbers is supported through the built in number function. By default the number formatting option defined either in the global settings or defined in the template settings gets applied. However, it is also possible to pass the required number formatting pattern as an argument ti the number helper function:

{{number numberField}}

{{number numberField format="0.0"}} --> round to one digit

swissqrbill

Using this helper directive, a QR code in the Swiss QR invoices standard can be created.

Assuming a data source structure like this:

Code Block
qrBillData: {
    options: {
      language: 'EN',
      svgWidth: 18.49,
      svgHeight: 9.34,
    },
    amount: 1994.75,
    creditor: {
      name: 'Creditor Company Inc',
      address: 'Creditor Street 77',
      zip: '12345',
      city: 'Creditor City',
      account: 'CH370029329311538901Q',
      country: 'CH',
    },
    currency: 'USD',
    debtor: {
      address: 'Teststreet',
      buildingNumber: 11,
      city: 'Testcity',
      country: 'CH',
      name: 'Peter Meter',
      zip: '4321',
    },
    reference: 'RF26102132000002000000',
  },
}

In the template a Swiss QR Bill can be created easily by using the following directive in the DOCX template:

{{swissqrbill data=qrBillData}}

...

replace

TODO

Control Directives

When using block helpers like conditions or loops it is important to define whether the function should be applied inline to the current text line on a whole paragraph with multiple lines, on a row or a cell in a table. To explicitly distinguish those use cases we need to advice IdealDoc with on of the following control directives. The @X directive should be added before a block start “#”, and “else” or an block end “/” expression.

@p

Should be used with a block expression on a single line. This instructs IdealDoc to delete the whole expression line after evaluation.

For example:

Code Block
{{@p#if true}}
Line 1
Line 2
{{@p/if}}

Produces the this result with two lines:

Code Block
Line 1
Line 2

The first and fourth line containing the #if and /if directives are completely removed.

WARNING: never combine directives with and without an @p or any other @ expression. This will result in a corrupt document. (e.g. {{@p#if true}} … {{/if}}

@tr

Should be used within a table row to indicate that the corresponding block expression will be applied to this row. This is needed for rendering rows dynamically based on a collection (with @tr#each) or to conditional show or hide a complete row (with @tr#if)

Example Template:

Header 1

Header 2

Header 3

{{@tr#if Discount}}Total Discount %{{@tr/if}}

{{Discount}}

@tc

Should be used within a table cell to indicate that the corresponding block expression will be applied to this cell. This is needed for rendering table columns dynamically based on a collection (with @tr#each) or to conditional show or hide a complete column (with @tr#if)

Table Example with dynamic rows and columns:

Header 1

{{@tc#if Show})Header 2 Optional{{@tc/if}}

Header 3

{{@tr#each People}}{{FirstName}}{{@tr/each}}

{{@tc#if ../Show}){{LastName}}{{@tc/if}}

{{Email}}