Understand handlebars
Last Update: Dec 2024 • Est. Read Time: 3 MINHandlebars is a templating language used to retrieve and display dynamic content. Its syntax consists of a set of {{double}}
or {{{triple}}}
curly braces wrapped around a block of data or dedicated handlebars helper. Statements made with handlebars may also be referred to as "handlebars expressions" or "handlebars blocks".
Handlebars are utilized as code, and are designed to output a string of text when called, commonly using a data path to do so. Handlebars may also use helpers to manipulate data, which have a great deal of utility in Kustomer workflows.
See Handlebars’ official documentation at https://handlebarsjs.com/guide to learn more.
In this article:
String interpolation & data paths
Handlebars allow for basic string interpolation of object attribute values. In workflow steps, an attribute value will commonly be referenced with workflow initiation command syntax, followed by the attribute's JSON data path (/#steps.STEP_ID.ATTRIBUTE_NAME
). However, the same value can also be referenced by wrapping the data path inside a handlebars expression ({{steps.STEP_ID.ATTRIBUTE_NAME}}
). This allows the attribute value to be interpolated within the context of a larger string.
As one example, you may wish to greet customers by name when using a workflow to send automated messages.
In this example, the body input field of a Send Message step is filled with the text Hi {{steps.GEKp2Gib.firstName}}!
The data path inside the handlebars dynamically retrieves and displays the first name of the customer found in the previous action step. If the customer's name is Mindy Sinclair, the output text will read "Hi Mindy!"
.
To better understand this process, and JSON data paths, the example can be broken down further into three parts:
steps
access the array of steps containing all previous output data generated by the running workflowGEKp2Gib
is the step ID of a specific previous step, contained within thesteps
arrayfirstName
is the attribute name for the value "Mindy", found in theGEKp2Gib
step
JSON data paths may be longer when attributes contain nested child data. For example, data received via webhook will usually be accessible within a data
object nested inside an attributes
object (steps.1.attributes.data
).
Formatting handlebars
When using a handlebars expression to interpolate or reference a string value, you can use double or triple curly braces (sometimes called a "triple-stache").
Characters returned from double handlebars will be HTML-escaped, while characters returned from a triple-stache will be considered "raw", with no change in appearance.
- Given steps.1.name = "Zak & Sara"
{{steps.1.name}}
resolves to the URL encoded string"Zak & Sara"
{{{steps.1.name}}}
resolves to the non-encoded string"Zak & Sara"
Because handlebars expressions are only capable of outputting a string value, they will always attempt to convert non-strings values into strings, with varying degrees of success.
- Given steps.1.attributes.data = {"string": "2", "number": 2, "boolean": true, "array": ["a", "b", 3], "object": {"nestedString": "2"}, "null": null}
{{steps.1.attributes.data.string}}
resolves to the string"2"
{{steps.1.attributes.data.number}}
resolves to the string"2"
{{steps.1.attributes.data.boolean}}
resolves to the string"true"
{{steps.1.attributes.data.array}}
resolves to the string"a,b,3"
{{steps.1.attributes.data.object}}
resolves to the string"[object Object]"
, which can be handled with additional helpers{{steps.1.attributes.data.null}}
resolves to an empty string
Nesting handlebars helpers
Expression helpers can be used as arguments inside other expression helpers through the use of subexpressions, which are enclosed in a set of parentheses. For example, {{helper (subexpression)}}
As an example, you may need to look up complex JSON data using the {{lookup}}
and {{toJSON}}
helpers:
{{{toJSON (lookup steps.1.attributes 'data')}}}
Or, you might choose to format a string with multiple string helpers:
{{{toLower (snakeCase steps.1.name)}}}
You may even wish to use multiple levels of subexpressions. For example, you might nest a {{date}}
helper inside a {{dateDiff}}
helper, which is then nested inside a {{math}}
helper.
{{{math (dateDiff 'days' to=(date 'days' count=-1)) '/' 2}}}
Both expression and block helpers can be nested between a block helper's opening and closing blocks as a sub-helper. For example, the {{formatCurrency}}
expression helper can be placed inside {{#ifCond}}
to determine how a number needs to be formatted.
{{#ifCond steps.1.custom.currencyCode '!=' 'USD'}}{{formatCurrency 100 currency=../steps.1.custom.currencyCode}}{{else}}{{formatCurrency 100}}{{/ifCond}}
Similarly, an {{#if}}
block helper can be placed inside {{#each}}
to determine which string to output in a loop.
{{#each steps.1.attributes.data.array}}{{#if this}}{{this}}{{else}}N/A{{/if}}{{/each}}