Skip to content

Appendix E: Handlebars Usage in Formbird

This document is currently being updated

1 Purpose

Handlebars is a templating language which is compatible with and can be used within a Formbird template.

The pupose of this document is to provide:

  1. An overview of the Handlebars templating language (refer Section 2)
  2. A description of how the Handlebars templating language can be used within a Formbird template (refer Section 3).
  3. Examples of Handlebars usage within a Formbird template (refer Section 4).
  4. Links to resources and further reading on the Handlebars templating language (refer Section 5).

2 Handlebars Templating Language Overview

The basic unit of the Handlebars templating language is the Handlebars expression.

Handlebars expressions are wrapped in double curly braces i.e. {{ some expression }}.

Expressions tell Handlebars to look up and use the value of a field or to execute helper functions.

Helpers allow you to execute simple logic, loop through arrays, manipulate data and more. Handlebars provides a number of built-in helpers such as the if conditional and the each iterator. You can also define your own helpers.

2.1 Basic Expressions

The simplest Handlebars expression is a field name wrapped in double curly braces which tells Handlebars to look up the field in the current context and use its value. When a Handlebars expression is written within a Formbird template, the current context will be the current Formbird document.

The Handlebars expression {{lastName}} means look up the lastName field in the current context and use its value. If the lastName field is not found then no value will be used.

Note: When using Handlebars in a Formbird template, field names within a Handlebars expression should be prefixed with "document." e.g. {{document.lastName}} . Hence in Formbird, the Handlebars expression {{document.lastName}} means look up the lastName field in the current Formbird document and use its value.

How it Works

graph TD A("FORMBIRD TEMPLATE<br/>&quot;summaryNameRule&quot;: &quot;Contact - {{document.firstName}} {{document.lastName}}&quot;") -->|Handlebars<br/>Compiler| B("function()") C("CURRENT FORMBIRD DOCUMENT<br/>&quot;firstName&quot;: &quot;James&quot &quot;<br/>lastName&quot;: &quot;McAllan&quot;") -->|"James<br/>McAllan"| B B-->|On execution|D("CURRENT FORMBIRD DOCUMENT<br/>&quot;summaryName&quot;: &quot;Contact - James McAllan&quot;<br/>&quot;firstName&quot;: &quot;James&quot;<br/>&quot;lastName&quot;: &quot;McAllan&quot;")

In the above diagram:

  1. A Formbird Template contains a "summaryNameRule" field whose value is defined as a concatenation of the text ''contact - '' and two Handlebars expressions separated by a space i.e.
    "summaryNameRule": "Contact - {{document.firstName}} {{document.lastName}}".

  2. The current Formbird document contains the fields
    "firstName": "James",
    "lastName": "McAllan"

  3. Handlebars takes the Handlebars expressions from the Formbird template and compiles them into a function.

  4. This function then executes, setting the values of Handlebars expression fields to the values of the corresponding fields in the current Formbird document.

  5. On execution of the function, the current Formbird document will have the "summaryName" field as shown below:

    "summaryName": "Contact - James McAllan".

2.2 Path Expressions

Handlebars expressions can also be dot-separated paths.

Example:

{{document.address.streetName}} means lookup the address field in the current Formbird document, then look up the streetName field in the result and use its value.

2.3 Block Expressions

In Handlebars, blocks are expressions that open with {{# }} and close with {{/ }}. Each of the Handlebars built-in helpers described in Section 2.4 below are examples of block expressions.

2.4 Built-In Helper Expressions

Handlebars provides a number of built-in helpers including the if, each, unless, and with block helpers. These built-in helpers provide the ability to execute simple logic.

Most built-in helpers are block expressions i.e. they open with {{# }} and close with {{/ }}. For example the if block helper opens with {{#if}} and closes with {{/if}}.

A Handlebars helper may be followed by parameters (separated by a space), as shown below:

{{#if parameter1 parameter2 ...}} Your content here {{/if}}

2.4.1 if Block Helper

The if block helper is used to conditionally execute a block expression. If the condition returns a truthy value, Handlebars will execute the if block. If the condition returns a falsy value, Handlebars will not execute the if block. The if block helper can also include an {{else}} section in order to define how to execute a falsy value.

Valid Falsy values in Handlebars are false, undefined, null, "", and [] where the latter two are the empty string and empty array.

Example 1:

A Formbird Template contains the Handlebars if block helper shown below:

{{#if document.countries}}Countries are present.{{else}}Countries are not present.{{/if}}

The current Formbird document contains the countries field shown below:

"Countries": [
  "Australia",
  "New Zealand",
  "France"
]

On execution, the if block helper would evaluate the non-empty "countries" array as a truthy value and return the result:

Countries are present.

Example 2:

A Formbird Template contains the Handlebars if block helper shown below:

{{#if document.countries}}Countries are present.{{else}}Countries are not present.{{/if}}

The current Formbird document contains the countries field shown below:

"Countries": []

On execution the if block helper would evaluate the empty "countries" array as a falsy value and return the result:

Countries are not present.

Example 3:

A Formbird Template contains the Handlebars if block helper shown below:

{{#if document.countries}}{{document.countries.[0]}}{{/if}}

The current Formbird document contains the countries field shown below:

"countries": [
  "Australia",
  "New Zealand",
  "France"
]

On execution the if block helper would evaluate the non-empty "countries" array as a truthy value and return the first value of the countries array, i.e. return:

Australia

2.4.2 unless Block Helper

The unlessblock helper is similar to the if block helper in that it is used to conditionally executes a block expression, except it operates on the falsy value i.e. the unless block helper is the inverse of the if block helper. If the condition returns a falsy value, Handlebars will execute the unless block. If the condition returns a truthy value, Handlebars will not execute the unless block. The unless block helper can also include an {{else}} section in order to define how to evaluate a truthy value.

Falsy values in Handlebars are false, undefined, null, "", and [] where the latter two are the empty string and empty array.

Example 1:

A Formbird Template contains the Handlebars unless block helper shown below:

{{#unless document.countries}}Countries are not present.{{else}}Countries are present.{{/unless}}

The current Formbird document contains the countries field shown below:

"countries": []

On execution, the unless block helper would evaluate the empty array as a falsy value and return the result:

Countries are not present.

Example 2:

A Formbird Template contains the Handlebars if block helper shown below:

{{#unless document.countries}}Countries are not present.{{else}}Countries are present.{{/unless}}

The current Formbird document contains the countries field shown below:

"countries": [
  "Australia",
  "New Zealand",
  "France"
]

On execution. the unless block helper would evaluate the non-empty array to a truthy value and return the result:

Countries are present.

2.4.3 each Block Helper

The each block helper is used to iterate over an array of items.

You can use {{this}} inside the each block to reference the array item being iterated over.

The following parameters can be used to provide additional information while iterating:

  • The {{@index}} parameter can be used inside the each block to access the current loop index. This index begins at 0 and increments by 1 with each iteration.
  • The {{@first}} parameter provides a boolean for implementing different logic for the first item when iterating over an array or a list of items.
  • The {{@last}} parameter provides a boolean for implementing different logic for the last item when iterating over an array or a list of items.

Example 1:

A Formbird Template contains the Handlebars each block helper shown below:

{{#each document.countries}}{{@index}}: {{this}};{{/each}}

The current Formbird document contains the countries field shown below:

"countries": [
  "Australia",
  "New Zealand",
  "France"
]

On execution, the each block helper would iterate over each value of the countriesarray and return the result:

0: Australia; 1: New Zealand; 2: France;

Example 2:

A Formbird Template contains a Handlebars each block helper shown below:

{{#each document.names}}
  {{#unless @last}}
    Name: {{document.firstName}} {{document.lastName}};
  {{else}}
    Name: {{document.firstName}} {{documemnt.lastName}}
  {{/unless}}
{{/each}}

The current Formbird document contains the names field shown below:

"names" : [
  {"firstName":"Mary","lastName":"McAllan"},
  {"firstName":"Reginald","lastName":"Katting"},
  {"firstName":"Emily","lastName":"Frousicker"},
  {"firstName":"Lily-Ann","lastName":"Arnott"}
]

On execution, the each block helper will iterate over each item of the names array and return the result:

Name: Mary McAllan; Name: Reginald Katting; Name: Emily Frousicker; Name: Lily-Ann Arnott

Note the unless block helper and the @last parameter were used to suffix each element of the array, except the last, with a semi-colon.

2.4.4 with Block Helper

The {{with}} block helper is similar to the if block helper in that it is used to conditionally executes a block expression , with one key difference.

Normally Handlebars first takes the Handlebars expressions from the Formbird template and compiles them into a function before evaluating the resulting function against the current Formbird document. Whereas the with block helper allows immediate access the current Formbird document.

If the condition returns a truthy value, Handlebars will immediately execute the with block. If the condition returns a falsy value, Handlebars will not execute the with block. The with block helper can also include an {{else}} section in order to define how to evaluate a falsy value.

Example:

A Formbird Template contains the Handlebars with block helper shown below:

{{#with document.author}}Written by {{document.firstName}} {{document.lastName}}{{else}}Unknown Author{{/with}}

The current Formbird document contains the author field shown below:

"author": {
    "firstName": "Lily-Ann",
    "lastName": "Arnott"
  }

The with block helper would immediately access the current Formbird document and return the result:

Written By Lily-Ann Arnott

3 Handlebars Usage in Formbird

Often the best and simplest way of deliveriing a particular requirement is via a Handlebars expression written within a Formbird template. For example:

  1. As shown above, the basic Handlebars expression {{document.lastName}} is an instruction to look up and use the value of the lastName field in the current Formbird document.
  2. The Handlebars built-in helpers described in Section 2.4 or Handlebars helpers defined by you can be used to incorporate logic within a Formbird template.

3.1 Use the value of a field in its current Formbird context

Generally the purpose of a Handlebars expression in a Formbird template is to look up and use the value of a field in its current Formbird context, which can be:

  • A field in the current Formbird document.
  • A field in the current Formbird document template.
  • A field in the current user's Formbird account document.
  • A field in the current Formbird component definition.
  • A field in the currently selected result returned by a Formbird filter query.
  • The total count of results returned by a Formbird filter query.
  • The array index of the currently selected result returned by a Formbird filter query.
  • The full set of results returned by a Formbird filter query.

When used within a Formbird template, the Handlebars expression format for each of the above Formbird contexts is shown in the table below.

Formbird Context Handlebars Expression Description Examples
Formbird document {{document.field name}} Look up and use the value of a field in the current Formbird document. {{document.lastName}}
Formbird document template {{tpl.field name}} Look up and use the value of a field in the current Formbird document template. {{tpl.documentId}}
Formbird component definition {{tplItem.field name}} Look up and use the value of a field in the current Formbird component definition. {{tplItem.name}}
Formbird account document ((account.field name)) Look up and use the value of a field in the current user's Formbird account document. {{account.systemHeader.summaryName}}
Formbird filter query result {{result.field name}} Look up and use the value of a field in the currently selected result returned by a Formbird filter query. {{result.pipe_dia}}
{{result.systemHeader.summaryName}}
Formbird filter query result {{resultsCount}} The total count of results returned by a Formbird filter query. {{resultsCount}}
Formbird filter query result {{resultsIndex}} The array index of the currently selected result returned by a Formbird filter query. {{resultsIndex}}
Formbird filter query result {{results}} The full set of results returned by a Formbird filter query.

For example a sc-selected-asset component with a tooltip field defined as:

"tooltips": "Displaying Pipes of type {{document.filterPipes}} Pipe #{{resultsIndex}} of {{resultsCount}} size {{result.pipe_dia}} mm <a href='/form/{{result.documentId}}' target='_blank'>{{result.systemHeader.summaryName}}</a> Current User {{account.systemHeader.summaryName}} viewing {{tplItem.name}}"

would generate and display a tooltip field as shown below:

4 Examples

Example 1

Requirement

In this example, the Formbird document is required to:

  1. Have its summaryName field value set to the concatenation of "Property - " with the values of each its street address fields i.e. its unit_No, streetNo, street, suburb and postcode fields.
  2. Handle street addresses that don't have a unit_No or a streetNo value so that the unit_No and " - " and streetNo is skipped.

Solution:

Define Formbird template to include the summaryNameRule field shown below:

"summaryNameRule": "Property - {{#with addressGeo.features.[0].properties}}{{#if unit_No}}{{unit_No}} - {{/if}}{{#if streetNo}}{{streetNo}} {{/if}}{{street}}, {{suburb}}, {{postcode}}{{/with}}"


Result

If the current Formbird Document contained the fields show below:

{
    "systemHeader": {
        "systemType": "document",
        "templateId": "cd02a730-6b11-11e9-98c0-e92fbfb6142f",
        "keyIds": [
         ],
        "createdDate": "2019-07-11T07:53:04.028Z",
        "createdBy": "65be85d0-66b8-11e7-b9f2-8fcf6a56c9da",
        "serverUpdatedDate": "2019-07-11T07:53:04.028Z",
        "serverCreatedDate": "2019-07-11T07:53:04.028Z",
        "versionId": "e99a35c0-a3b0-11e9-b25d-1d82576c71d1",
        "currentVersion": true,
    },
    "documentId": "e915ea92-a3b0-11e9-b25d-1d82576c71d1",
    "addressGeo": {
        "type": "FeatureCollection",
        "features": [
            {
                "type": "Feature",
                "properties": {
                    "type": "street",
                    "unit_No": "",
                    "streetNo": "600",
                    "street": "SNEYDES ROAD",
                    "suburb": "WERRIBEE",
                    "postcode": "3030",
                    "state": "VIC"
                },
                "geometry": {
                    "type": "Point",
                    "coordinates": [
                        144.68618641755836,
                        -37.897783153444955
                    ]
                }
            }
        ]
    },
    "status": "Active"
}

Then the with block helper would immediately access its street address fields and and include the summaryName field shown below in the current Formbird document:

"summaryName": "Property - 600 SNEYDES ROAD WERRIBEE, 3030"

5 Resources and Further Reading

Listed below are a few more resources and articles if you wish to dig deeper into the Handlebars templating language: