Articles in this section

Handlebars helper reference

Handlebars helpers can be used to implement functionality that is not part of the handlebars language itself. The following list of helpers is supported by integrator.io:

Tip

Press the Home key to return to the top of this article (Fn +Left Arrow for Mac).

Custom helpers

abs

Returns the absolute value of a number.

{{abs number}}

number: This parameter can either be a field that returns a number value or a hard-coded number value.

Template

Context

Output

{{abs field1}}
{
  "field1": "-123"
}
123

add

Adds all numeric values (integers, floats, or decimals). Parameters can either be a field that returns a number value or a hard-coded number value.

{{add number1 number2 ...}}
  • number1: Numeric field or hard-coded integer, float, or decimal.

  • number2: Numeric field or hard-coded integer, float, or decimal.

Absolute values do not require context JSON variables. The example below only shows integers, but it also works with floats and decimals.

Template

Context

Output

{{add item1 item2 item3}}
{
  "item1": "33",
  "item2": "11",
  "item3": "100"
}
144
{{add "2" "5" "2"}}
9
{{add item1 "2" "3" item3}}
 138

avg

Computes the average of all specified numeric values (integers, floats, or decimals). Parameters can be either JSON fields or hard-coded values. Absolute values do not require Context JSON variables.

{{avg number1 number2 ...}}
  • number1: Numeric field or hard-coded integer, float, or decimal.

  • number2: Numeric field or hard-coded integer, float, or decimal.

Template

Context

Output

{{avg item1 item2 item3}}
{
  "item1": "33",
  "item2": "11",
  "item3": "100"
}
48
{{avg "2" "5" "2"}}
3
{{avg item1 "2" "3" item3}}
34.5

aws4

Generates a signature for Amazon Web Services (AWS) and authenticates requests with AWS Signature Version 4. The authentication information is added to AWS API requests sent by HTTP.

{{{aws4 accessKey secretKey sessionToken region serviceName}}}
  • accessKey: The access key for your AWS account.

  • secretKey: The secret key for your AWS account.

  • sessionToken: If your service does not require a session token use null or an empty string ("").

  • region: Use an empty string (""), to calculate a default signature from the base URL.

  • serviceName: Use an empty string (""), to calculate a default signature from the base URL.

For sessionToken , you can use null or an empty string ( "") if a session token is not being used by the service.

{{{aws4 accessKey secretKey null region serviceName}}

For region and serviceName if you use null or an empty string ( ""), integrator.io calculates a default based on the base URL and then the signature is accordingly calculated.

{{{aws4 accessKey secretKey null null null}}}

The signature calculated in this case might not be the same as the signature calculated by AWS. Hence, we recommend that you provide values for region and serviceName.

Template:

{{{aws4 accessKey secretKey sessionToken region serviceName}}}

Context:

{
  accessKey: "AKIA●●●●●●●●●●●●●●●●",
  secretKey: "t●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●A",
  sessionToken: "s●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●g",
  region: "us-east-1",
  serviceName: "execute-api"
}

Output:

<Signature>

If the values are configured in the encrypted field of your HTTP connection, then you must provide the handlebar helper like this:

{{{aws4 connection.http.encrypted.accessKey connection.http.encrypted.secretKey connection.http.encrypted.sessionToken region serviceName}}}

Note

If you are using the authorization (aws4 handlebar helper) in the HTTP Authorization header of the request, you must also provide the X-Amz-Date header as shown below.

{{timestamp "YYYYMMDDTHHmmss" "Etc/GMT-0"}}Z

base64Decode

Decodes any Base64 string to the specified encoding format.

{{base64Decode base64String "decodeFormat"}}
  • base64String: The encoded string value to be decoded

  • decodeFormat (optional): The optional binary-to-text encryption format to be decoded. This value can be any of the following:

    • "ascii"

    • "base64"

    • "hex"

    • "ucs2" or "ucs-2"

    • "utf16le" or "utf-16le"

    • "utf8" or "utf-8" (default)

    • "binary"

    • "latin1"

Template

Context

Output

{{base64Decode str}}
 str = 'SGVsbG8gV29ybGQhIQ=='
Hello World!!
{{base64Decode str "utf8"}}
{{base64Decode null}}
' '
{{base64Decode undefined}}
{{base64Decode str "ascii"}}
Hello World!!
{{base64Decode str "binary"}}
{{base64Decode str "hex"}}
48656c6c6f20576f726c642121
{{base64Decode str str "utf8"}}
Error: handlebars Helper {{base64Decode}} expects maximum 2 arguments only.
{{base64Decode str 
"wrongEncodingFormat"}}
Error: wrongEncodingFormat encoding format is not supported.

base64Encode

Encodes the base64String field to the specified binary-to-text encoding format.

Note: Use triple-curly braces for this expression.

{{{base64Encode Base64String "encodeFormat"}}}
  • base64String: The value to be encoded. This can be a field that returns string values or a hard-coded string.

  • encodeFormat (optional): The optional binary-to-text encryption format to be encoded. This value can be any of the following:

    • "ascii"

    • "base64"

    • "hex"

    • "ucs2" or "ucs-2"

    • "utf16le" or "utf-16le"

    • "utf8" or "utf-8" (default)

    • "binary"

    • "latin1"

Template

Context

Output

{{{base64Encode userName}}}
{
  "connection": {},
  "userName": "username",
  "pwd": "password"
}
dXNlcm5hbWU=
{{{base64Encode userName pwd}}}
dXNlcm5hbWVwYXNzd29yZA==
{{{base64Encode userName ":" pwd}}}
dXNlcm5hbWU6cGFzc3dvcmQ=

capitalize

Capitalizes the first letter of the first word in a string.

{{capitalize field}}

Template

Context

Output

The {{capitalize type}} is a 
member of the {{animal}}
species.
{
  "animal":"canine",
  "type": "dog"
}
The Dog is a 
member of the canine
species.
{{capitalize day}}
{
  "hour": "minutes away",
  "minute": "seconds away",
  "day": "this is the day!"
}
This is the day!

capitalizeAll

Capitalizes the first letter of all the words in a string.

{{capitalizeAll field}}

Template

On this day, the {{capitalizeAll type}} . . .

Context

{
  "animal":"canine",
  "type": "dog, wolf, extant grey wolf"
}

Output

On this day, the Dog, Wolf, Extant Grey Wolf . . .

ceil

Returns the value rounded up to the nearest whole number.

{{ceil field}}

Template

Context

Output

{{ceil item1}}
{{ceil item2}}
{{ceil item3}}
{
  "item1": "45.75",
  "item2": "62.92",
  "item3": "45.02"
}
46
63
46

dateAdd

Adds or subtracts the specified offset value from the specified date and returns the result in the specified time zone in ISO 8601 format.

{{dateAdd dateField offsetField timeZoneField}}
  • offsetField: The amount of time in milliseconds to add to the date value. Prepend this value with a minus sign to subtract.

  • timeZoneField (optional): Specifies the timezone. If not included in the expression, the time zone offset is not included in the resulting ISO timestamp.

Both of these fields are discussed in further detail below.

Note: not all of the fields in the default expression need to be present, as shown in some of the examples. See also: dateFormat and timestamp.

In this example, the timeZoneField is set to New York and the offsetField is shifted one day ahead (in milliseconds.) This will render the date one day ahead of what is in the Context. New York is -5:00 UTC, as shown in the output.

Template

{{dateAdd dateOrders "107280000" "America/New_York"}}

Context

{
  "dateOrders": "12/14/2019"
}

Output

2019-12-15T00:48:00-05:00

dateField

{{dateAdd dateField offsetField timeZoneField}}

In the first example below, the offset and timeZone fields have been removed and only the referenced object name:value pair in the Context file will be passed to the output.

The second example shows the offsetField set to one day behind, and is reflected in the output.

The third example shows the timeZone Field entered with no offset entered.

Template

Context

Output

{{dateAdd dateOrders}}
{
  "dateOrders":
  "11/5/2019 3:25 PM"
}
2019-11-05T15:25:00.000Z
{{dateAdd dateOrders "-86400000"}}
2019-11-04T15:25:00.000Z
{{dateAdd dateOrders "" "America/Los_Angeles"}}
2019-11-05T07:25:00-08:00

You can also enter a fixed date value in quotes:

{{dateAdd "Mon Nov 21 2019 20:08:40 GMT+0000"}}

Or you can add a standard date and the system will automatically format the output to ISO specification:

{{dateAdd "Nov 21, 2019"}} will output: 2019-11-21T00:00:00.000Z

offsetField

This field allows the date to be set to a hard-coded string.

{{dateAdd dateField offsetField timeZoneField}}

Time values are expressed in milliseconds

  • “86400000” = one day ahead (86,400,000 ms);

  • "107280000"= two days ahead (107,280,000 ms);

  • “-86400000” = one day behind (-86,400,000);

  • Calculate milliseconds here

  • Scientific notation may also be used: “1E6” = 1M (10^6 or 1,000,000 ms).

Template

Context

Output

{{dateAdd dateOrders "86400000"}}
{
  "dateOrders": "12/14/2019"
}
2019-12-15T00:00:00.000Z
{{dateAdd dateOrders "172800000"}}
2019-12-16T00:00:00.000Z
{{dateAdd dateOrders "-86400000"}}
2019-12-13T00:00:00.000Z
{{dateAdd date "3.888e+9}}
"Wed Aug 08 2019 17:27:13 GMT+0530"
2019-09-22T11:57:130.000Z
Setting the date using offsetField
  • The date offset in the first template is set to “86400000” (one day) and the output reflects the date as one day ahead of the dateOrders field in the Context; doubling this number will place the date two days ahead of the date in the value;

  • The second example has the original offsetField value doubled “172800000” (two days);

  • Conversely, placing a minus sign before the numeric value “-86400000” will subtract one day from the date.

  • The fourth example uses scientific notation to increase a date value by 45 days. These offsets must be in milliseconds.

timeZoneField

This field uses standard ISO string date format where the offset value is subtracted from the specified date along with time zone. See integrator.io supported time zones.

{{dateAdd dateField offsetField timeZoneField}}

Here, the offsetField is set to null “ ” which will output the time in Hong Kong local time which is +8 UTC.

{{dateAdd dateField "" "Asia/Hong_Kong"}}

Template

{{dateAdd dateOrders "" "Asia/Hong_Kong"}}

Context

{
  "dateOrders": "12/14/2019"
}

Output

2019-12-14T08:00:00+08:00

The following examples show the conversion to UTC/GMT/Zulu time. Note that New York is -5 and Hong Kong is +8.

Template

Context

Output

{{dateAdd dateOrders " "}}
{
  "dateOrders": "11/5/2019 3:25 PM"
}
2019-11-05T15:25:00.000Z
{{dateAdd dateOrders "" "America/New_York"}}
019-11-05T10:25:00-05:00
{{dateAdd dateOrders "" "Asia/Hong_Kong"}}
2019-11-05T23:25:00+08:00

dateFormat

This helper allows the adjustment and transformation of time and date fields to be output in a particular format and altered according to your needs. The date and time fields are not all required in an expression, and they can be used in a modular fashion.

{{dateFormat o/pformat date i/pformat timezone}}

For current UTC and world time zones, see Wikipedia's list of tz database time zones.

The default date conforms to ISO specification:

  • Structure: YYYY-MM-DD[T]hh:mm:ss.sss[Z]

  • Output: 2019-11-12T21:02:32+00:00

    • The date above is Nov 12, 2019, 1:02:32 PM PDT= 9:02:32 PM UTC

Time and date format codes:

  • YYYY: four-digit year

  • MM : two-digit month (01=January, etc.)

  • DD : two-digit day of month (01 through 31)

  • [T]: Time displayed as Coordinated Universal Time (UTC)

  • HH: two digit hours (00 through 23)

  • Note

    Use with a (am/pm) or A (AM/PM).

  • mm: two digit minutes (00 through 59)

  • ss : two digit seconds (00 through 59)

  • SSS: one or more digits representing a decimal fraction of a second

  • [Z]: expressed in Handlebars as "Zulu Time". If Z is present at the end of the date field, the time at this point will be expressed as Zulu time: +00:00

  • a: am or pm

  • A: AM or PM

For a complete list of all available time and date format codes, see Time and date format codes.

o/pformat

This field allows you to define the time and date format in the template which will be output accordingly. This field also works in concert with the "i/p format" field, which is discussed in further detail below.

{{dateFormat o/pformat date i/pformat timezone}}

Note: All date formats are placed in double quotation marks.

  • “MM-DD-YYYY” = 01-01-2020

  • “MM/DD/YYYY” = 01/01/2020

  • “YYYY.DD.MM” = 2020.31.01

Template

{{dateFormat "MM-DD-YYYY hh:mm" dateOrders "YYYY-DD-MM hh:mm"}}

Context

{
  "dateOrders": "1966-25-05 10:36"
}

Output

05-25-1966 10:36

date

This field passes the current date to the output unless specified in the context file. The following example shows how to print the current date in the format specified in the o/pformat field in the template.

Template

Context

Output

{{dateFormat "MM-DD-YYYY" date}}
{
}
02-26-2020

i/pformat

This field is the date object referenced in the Context. It can be hard-coded directly in the expression:

{{dateFormat o/pformat date i/pformat timezone}}

o/pformat vs. i/pformat:

  • Output format (o/pformat) is where you define the desired output format

  • Input format (i/pformat) is where you define the "input" format contained in the Context file

In the example below, the JSON Context format is "year/day/month" (1966/25/05). To output the date in the standard US format, define this format in the "o/pformat" field, as shown.

Template

{{dateFormat "MM-DD-YYYY hh:mm" dateOrders "YYYY-DD-MM hh:mm"}}

Context

{
  "dateOrders": "1966-25-05 10:36"
}

Output

05-25-1966 10:36

timezone

This fields utilizes standard ISO string date format where the offset value is subtracted from the specified date along with time zone. See integrator.io supported time zones.

{{dateFormat o/pformat date i/pformat timezone}}

In the example below, note the "Z" in the o/p format field? this is telling the system to output the timezone assigned in the "timezone" field and adjust the time automatically for the chosen timezone-Los Angeles.

Template

{{dateFormat "MM-DD-YYYY hh:mmZ" dateOrders "YYYY-DD-MM hh:mm" "America/Los_Angeles"}}

Context

{
  "dateOrders": "1966-25-05 10:36-8:00"
}

Output

05-25-1966 03:36-07:00

decodeURI

Decodes the specified URI. This example decodes the sample dataset from the “encodeURI” example.

{{{decodeURI field}}}

Note: This expression uses three curly braces.

Template

{{{decodeURI orders}}}

Context

{
  "orders": "overseas%20order%20flow"
}

Output

overseas order flow

The URI may also be a “hard-coded” value declared in the expression.

Template

{{{decodeURI "overseas%20order%20flow"}}}

Context

{
}

Output

overseas order flow

If you do not want the parameters inside the placeholder to be encoded (called escaping), use three brackets {{{ }}} - especially, when you intend to perform an encode/decode operation on the strings provided in the argument list (e.g. base64Encode or decodeURI).

HTML Encoded

{{placeholder}}

HTML and URL Encoded

{{encodeURI field}}

URL Encoded

{{{encodeURI field}}}

No Encoding Applied

{{{ placeholder }}}

divide

Returns the resultant quotient of two specified values. This helper returns the quotient of two variables, “hard-coded” values, or a combination thereof. Absolute values do not require context JSON variables.

{{divide field}}

Template

Context

Output

{{divide item1 item2}}
{
  "item1": "33",
  "item2": "11",
  "item3": "100"
}
3
{{divide 2002 100}}
20.02
{{divide item1 3}}
11

encodeURI

This helper expression encodes the specified uniform resource indicator (URI), enclosed in three curly braces.

{{{encodeURI field}}}

Certain characters are used to encode and are not allowed in the source value:

, / ? : @ & = + $ #

Tip: Call decodeURI to decode a previously encoded URI.

Template

{{{encodeURI orders}}}

Context

{
  "orders": "overseas order flow"
}

Output

overseas%20order%20flow

The value may also be declared as a “hard-coded” in the expression with the same output:

{{encodeURI "sample data type"}}

floor

This helper is the inverse of ceil. Floor returns the largest integral value that is less than or equal to the specified number. Floor rounds down a value to the nearest whole number.

{{floor field}}

Template

Context

Output

{{floor 22.44}}
{
}
22
{{floor 45.25}}
45
{{floor 3.14}}
3

getValue

This helper returns the value from the specified field.

{{getValue field "defaultValue"}}

Template

Context

Output

{{getValue "legends.unicorns" "defaultValue"}}
{
  "legends": {
    "unicorns": "11",
    "ponies": "22",
    "horses": "33",
    "total": " "
  }
}
11
{{getValue "legends.ponies" "defaultValue"}}
22 
{{getValue "legends.total" "defaultValue"}}
null 
{{getValue "name" defaultValue}}
{{getValue "state" defaultValue}}
{
  "state": "MO",
  "name": "Harry S Truman",
  "qty": "100",
  "ERP_Item": "kit"
}
Harry S Truman
MO

Note

The getValue helper method was introduced to retrieve the value from the complete path in the helper method's first argument. The getValue helper fails if used inside the #each block helper because getValue can't derive the complete path for the context of each data iteration.

Examples: This helper is especially helpful if you need to get the name of a field that is dynamically generated. For example:

{
    "date": "2021-01-09",
    "2021-01-09": "3"
}

To retrieve the value for "2021-01-09" (a dynamically generated field name based on another field value), the field name is unknown until the record is processed. You can use getValue to identify that field name by looking at the value for the "date" field.

{{getValue (getValue "date")}}

Another example would be as follows:

{
    "date": "2021-01-09",
    "hours": {
        "2021-01-09": "3"
    }
}

Since getValue is a helper method, you can nest other helper methods inside it, which opens up multiple options for dynamically generating the field name.

{{getValue (join "." "hours" (getValue "date"))}}

hash

Use this handlebar helper to cryptographically encode field values.

{{hash algorithm encoding field}}

Template

Context

Output

{{{hash "md5" "base64" name}}}
{
     "id": 123,
     "name": "Bob",
     "age": 33
}
sGiTHMRQRCtj9bPSdupClw==
{{{hash "md5" "hex" name}}}
b068931cc450442b63f5b3d276ea4297

See Supported cryptographic encoding algorithms.

hmac

Keyed-hashing for message authentication (HMAC) is a message authentication code generated via cryptographic hash function (such as MD5, SHA-256 and many more). This crypto key wraps the data until it is authenticated using a shared key. For a complete list of integrator.io support, see Supported cryptographic encoding algorithms. Never use "hmac" as the name of a variable.

{{hmac "algorithm" key "encoding" field keyEncoding}}
  • algorithm - accepts any integrator.io supported cryptographic encoding algorithm.

  • key - the path to the encryption key (in dot notation).

  • encoding - encoding type of the sent key ("hex" or base64").

  • field - the path to the incoming parameter (in dot notation).

  • keyEncoding (optional) - encoding type of the incoming key (currently only supports utf8 and base64). By default, incoming key encoding is assumed to be in utf8 format.

In this example, the key would be your secret key, or private access key.

Note

Be cautious about exposing the secret key, potentially compromising your system credentials.

Connection details:

  • HTTPS should be used, where standard HTTP should be avoided wherever possible

  • All PARAMETER values must be URI encoded

  • Authorization HEADER {{hmac}} helper must use the "full URL" keyword as the input as the system will calculate the signature based on the complete URL that it receives, including PARAMETER values and the Base URI https

  • HMAC handlebars do not support use of dot notation to reference record.<property>

See Using hmacOptions for additional functionality.

join

Joins field names using the specified delimiter and can handle any number of arguments.

{{join delimiterField field1 field2}}

delimiterField: The delimiter character(s) inserted between joined field names. Can be (parentheses) {braces} [brackets] or /*

Notes:

  • If a delimiter array is specified, the specified delimiter is introduced between each array value in the result set

  • If a string is specified, the specified subsequent variables are read and the specified delimiter is introduced between them in the result set

Template

Context

Output

{{join "**" "unicorns" "ponies"}}
{
  "legends" : {
    "unicorns": "11",
    "ponies": "22",
    "horses": "33",
    "total": " "
  }
}
unicorns**ponies
{{join " + " "unicorns" "ponies" "horses"}}
unicorns + ponies + horses
{{join "-" "unicorns" "ponies" "horses"}}
unicorns-horses
{{join "-" "legends" "[unicorns, ponies, horses]"}}
legends-[unicorns, ponies, horses]
{{join ", " sundayDrivingMusic}}
{
  "legends" : {
    "unicorns": "11",
    "ponies": "22",
    "horses": "33",
    "total": " "
},
  "sundayDrivingMusic": [
    "Iron Maiden",
    "DIO",
    "(old)Metallica",
    "Snoop"
  ]
}
"Iron Maiden, DIO, (old)Metallica, Snoop"

jsonEncode

Encodes the specified JSON object.

{{jsonEncode field}}

Template

Context

Output

{{jsonEncode total}}
{
  "orderId": "2468",
  "total": "99.99",
  "state": "ME"
}
99.99

jsonSerialize

The jsonSerialize function converts an object value into a JSON serialized string. Three curly braces are used in this expression.

{{{jsonSerialize field}}}

Template

{{{jsonSerialize elementals}}}

Context

{
  elementals: {
    gnomes: "677",
    salamanders: "422",
    sprites: "56",
    faeries: "277"
  }
}

Output

{gnomes:"677",salamanders:"422",sprites:"56",faeries:"277"}

lookup

This expression can only be used to reference a static or dynamic lookup that has been previously created in the current flow step by lookup name. Note that you can't use this expression to reference lookup flow steps or lookups created in other flow steps.

Dynamic mapping:

{{lookup.<lookup name>}}
Ex:
{{lookup.typeLookup}}

Static mapping:`

{{lookup '<lookup name>' this.<Export Field Name>}}
Ex:
{{lookup 'vendor_status' this.ExportFieldName}}

lowercase

Converts all letters in a string to lowercase.

{{lowercase field}}

Template

{{lowercase 'HERE WE GO!'}}

Context

{
}

Output

here we go!

multiply

Returns the multiplication of the two specified values. Variables may be referenced in context, or as “hard-coded” values.

{{multiply field}}

Template

Context

Output

{{multiply unicorns "5"}}
{
  "unicorns": "11",
  "ponies": "22",
  "horses": "33"
}
55
{{multiply "5" "2"}}
10
{{multiply horses ponies}}
726
{{multiply Field1 -1}}
{
  "Field1": "-22211.4",
}
22211.4

random

Generates a random alphanumeric string with an optional input field for the length. The first argument must be either “crypto” or “uuid”, and the default length is 32 characters.

Note

When mapping to NetSuite, you can also pass "number" as the first argument. The output will be a numeric string (instead of an alphanumeric string): {{random "number" 9}}

{{random "crypto" length}}

or

{{random "uuid" length}}
  • "crypto" or "uuid": the method for random alphanumeric string generation

  • "length": integer value for the number of characters in the output

Template

Context

Output

{{random "uuid" 5}}
{
}
5e3ca
{{random "crypto" 8}}
4ccb3420

regexMatch

Matches the input data based on the regular expression and returns the data based on index and options variables.

{{regexMatch field regex index options}}
  • field: the field name containing the variable or values to be matched against. For example, CustomerID would be the field name containing the string value you are running the regex match request on. You can reference a field or variable by typing its name without double quotes (or curly braces or parens).

  • regex: the regular expression pattern to match against existing values. For example, if your regex pattern is [a-zA-Z][0-9][0-9], a match occurs the first time any capital or lowercase letter is immediately followed by two numeric characters.

  • index: the location of the numerical range to be examined when searching for matches returned. For example, if your regex pattern is [0-9][0-9][0-9], matches will occur the first time three consecutive numeric characters are adjacent in the field value. The index defaults to 0. If you enter an index value of 1, you will only match on the second occurrence of three adjacent number characters.

  • options: modifies the search flag of the expression. For example, regular expressions stop at the first match in the text content by default. The "g" flag indicates that the regular expression should be tested against all possible matches in a string. See Advanced searching with flags.

    • d - Generate indices for substring matches.

    • g - Global search.

    • i - Case-insensitive search.

    • m - Allows ^ and $ to match newline characters.

    • s - Allows . to match newline characters.

    • u - "Unicode"; treat a pattern as a sequence of Unicode code points.

    • y - Perform a "sticky" search that matches starting at the current position in the target string.

Template

Context

Output

{{regexMatch secretCode "7" "[0-9]"}}
{
  "secretCode": "007"
}
7
{{regexMatch secretCode "007" "[0-9]"}}
007
{{regexMatch secretCode "[0-2][0-2][5-7]"}}
007
{{regexMatch secretCode "[0-9][0-9][0-9]" 1 "g"}}
{
  "secretCode": "123 3456 678 celigo 32"
}
345

regexReplace

The regexReplace helper returns a modified string where the pattern has been replaced.

{{regexReplace search replacement regex options}}
  • search: the value or field name to be replaced. You can reference a field or variable by typing its name without double quotes (or curly braces or parens).

  • replacement: the new value that will replace the matching value in regex.

  • regex: the regular expression that you’re searching for.

  • options: modifies the search flag of the expression. For example, regular expressions stop at the first match in the text content by default. The "g" flag indicates that the regular expression should be tested against all possible matches in a string. See Advanced searching with flags.

In this example, the output has the word “Sequence” replacing the number 6 in the Context.

Template

{{regexReplace secretCode "Sequence" "[6]"}}

Context

{
  "secretCode": "1234567890"
}

Output

12345Sequence7890

Alternately, you could change the price of an incorrect value by entering the number to change and assigning the value of the overwrite. Here, we have modified $249.99 to $549.99 and $9.99 to $19.99 respectively.

Template

Context

Output

{{regexReplace total "5" "[2]"}}
{
  "items": "orders",
  "total": "$249.99",
  "tax": " "
}
$549.99
{{regexReplace total "19" "[9]"}}
{
  "items": "orders",
  "total": "$9.99",
  "tax": " "
}
$19.99

You can use the following regexReplace expression to remove leading zeros from a field value.

Template

Context

Output

{{regexReplace id "" "^0+" "g"}}
{
  "id": "000000157"
}
157

See also Regular expressions (regex).

regexSearch

The regexSearch helper uses an expression to search for a match, and returns the position of the result in the dataset, where 0=first position and 2=third position.

{{{regexSearch field regex options}}}
  • field: the field name containing the variable or values to be replaced.

  • regex: the new value which will replace the existing value.

  • options: modifes the search flag of the expression. For example, regular expressions stop at the first match in the text content by default. The "g" flag indicates that the regular expression should be tested against all possible matches in a string. See Advanced searching with flags.

Template

{{regexSearch total 5}}

Context

{
  "items": "orders",
  "total": "$1499.95",
  "tax": " "
}

Output

7

(where 5 is the eighth value (INDEX location=7) in the “total” JSON field value)

replace

Replaces all the occurrences of the specified letter in a string with another letter.

{{replace field string string}}

Template

Context

Output

{{replace cases "&" "and"}}
{
  "cases": "these & those & some other cases"
}
these and those and some other cases
{{replace description "Shoes" "Boots"}}
{
  "description": "Shoes",
  "qty": 1
}
Boots

round

Rounds a decimal number value up or down to the nearest whole number value.

{{round field}}

Template

{{round vat}}

Context

{
  "vat": "29.77"
}

Output

30

sort

This helper sorts the specified values in ascending or descending order based on the value specified in the ”reverse” parameter. By default, this helper sorts the array variables in an ascending manner. If the input array contains numerical variables for sorting, set the number parameter = "true". You can also combine reverse and number option parameters in the handlebars expression.

{{sort field number="true" reverse="true"}}

Template

Context

Output

{{sort items number="true"}}
{
  "items": ["2","1","4","5","3"]
}
1,2,3,4,5 
{{sort items reverse="true"}}
5,4,3,2,1
{{sort items}}
{
  "items": ["candy", "hat", "toy"]
}
candy,hat,toy

split

Splits a series of words separated by delimiters in the context based on an index value, where 0=first position and 2=third position.

{{split field delimiter index}}

Template

Context

Output

{{split fullName "-" 0}}
{
  "fullName": "Hillary-Ann-Swank"
}
Hillary
{{split fullName "-" 1}}
Ann
{{split fullName "-" 2}}
Swank
{{split fullName "-" 0}}
{{split fullName "-" 1}}
{{split fullName "-" 2}}
Hillary
Ann
Swank

subtract

Returns the remainder of two values.

{{subtract minuend subtrahend}}
These are just mathematical terms for:
{{subtract value value}}

You can subtract the values of two fields, integers, or strings in this handlebars expression. If you are passing fields or integers, do not use quotes. If you are using string values, make sure to use quotes.

Template

Context

Output

{{subtract "6" "3"}}
{
  "unicorns": "11",
  "ponies": "22",
  "horses": 33,
  "total": "66"
}
3
{{subtract 6 3}}
3
{{subtract "6" ponies}}
-16
{{subtract horses "6"}}
27
{{subtract ponies unicorns}}
11

substring

Returns a substring of the specified string. This is useful for shortening the names of longer field names.

{{substring stringField startIndex endIndex}}
  • stringField is the actual string

  • startIndex is index of the actual at which the substring starts, where 0=first position and 2=third position

  • endIndex is the index of the actual string where the substring ends, where 0=first position and 2=third position

  • endIndex acts like JavaScript and is non-inclusive

Template

Context

Output

{{substring "itemizationCode" "0" "4"}}
{
}
item
{{substring "inventory" "0" "3"}}
inv
{{substring memo "10" "19"}}
{"memo": "The quick brown fox jumped over the lazy dog"}
brown fox

Note

Don't encase an object name in quotes when using substring to reference its value.

sum

Computes the sum of all numbers present in the specified array. The example below only shows integers, but it also works with floats and decimals.

Note: this is different from the add helper function and performs additional calculations.

{{sum field1 field2 field3}}

Template

Context

Output

{{sum items}}
{
  "items": [2,5,7,8,9]
}
31
{{sum items}}
{
  "items": [
    50 , 10 , 10 , 10 , 5 , 5 ,
    60 , 10 , 10 , 10 , 5 , 5 ,
    50 , 10 , 10 , 10 , 10 , 10 
  ]
}
290
{{sum (multiply 2 55)}}
{
}
110

timestamp

Returns a timestamp in the format and timezone provided.

  • If no timestamp format is provided, this function defaults to ISO8601.

  • If no timezone is provided, this function defaults to the UTC timestamp and ignores the timezone set in your profile settings.

Important

Celigo recommends that you always set the timezone parameter when using the timestamp helper instead of relying on the default timezone.

{{timestamp format timezone}}

The first example below shows the local time in Los Angeles, which is 09:27:46 (HH:MM:SS), but is followed by the Zulu time offset (-08:00).

In the second example, the current time is displayed in Zulu time (as the server is configured).

Template

Context

Output

{{timestamp HH:MM:SS "America/Los_Angeles"}}
{
} 
2021-02-05T09:27:46-08:00
{{timestamp HH:MM:SS}}
2021-02-05T17:38:20.715Z

toExponential

Returns a string representing the specified number in an exponential format. Variables may be referenced in context or as “hard-coded” values.

{{toExponential field fractionDigits}}
  • field: is the number or object value to be modified;

  • fractionDigits: an optional parameter that will display the provided number of digits after the decimal place.

Template

Context

Output

{{toExponential orderId 2}}
{
  "orderId": "12345",
  "total": "99.99"
}
1.23e+4
{{toExponential "12345" 2}}
{
} 
1.23e+4
{{toExponential "3.14159265359" 6}}
3.141593e+0

toFixed

This will set a fixed numerical value to the output string, and format the number to a fixed number of decimal places.

{{toFixed field digits}}
  • field: the number to be modified

  • digits: number of decimal places to be displayed

{{toFixed 123.456789 0}} = 123
{{toFixed 123.456789 1}} = 123.5
{{toFixed 123.456789 2}} = 123.46
{{toFixed 123.456789 3}} = 123.457
{{toFixed 123.456789 4}} = 123.4568
{{toFixed 123.456789 5}} = 123.45679

toPrecision

This outputs scientific notation if there are more integer digits (before decimals) than the specified precision.

{{toPrecision field precision}}
  • field: the number to be modified

  • precision: number of decimal places to be displayed

{{toPrecision 123.00 0}} = 1e+2
{{toPrecision 123.00 1}} = 1e+2
{{toPrecision 123.00 2}} = 1.2e+2
{{toPrecision 123.00 3}} = 123
{{toPrecision 123456.00 5}} = 1.2346e+5
{{toPrecision 1234567.00 6}} = 123456

trim

This helper will remove (trim) any white space in a Trims whitespace characters present at the beginning and at the end of the string.

{{trim field}}

Use the trim field if you have white space that persists in your file across all values. Here, the whitespace is before the “artist” value as seen in the output like this:

handlebarHelpersSnip.png

The problem is also evident in the context below, and the example shown in the Template will resolve the white space issue in the output.

Template

Context

Output

{{trim library.artist}}
{
  "library": {
    "album": "The Sound",
    "title": "Danube Incident",
    "artist": " Lalo Schifrin"
  }
}
Lalo Schifrin

uppercase

Converts all lowercase characters in the JSON field value or string to uppercase.

{{uppercase field}}

Template

Context

Output

{{uppercase "library"}}
{
}
LIBRARY
The {{uppercase family.type}} is a member
of the {{uppercase family.animal}} family
{
  "family": {
    "animal":"canine",
    "type": "dog"
  }
}
The DOG is a member
of the CANINE family

Block Helpers

Block helpers have a hash symbol at the beginning.

#and

The #and block helper renders the expression if both of the specified parameters are true (according to JavaScript rules). If the result is false, the {{else}} expression prints in the output. If the field is undefined, null, or an empty string, it will evaluate as false, otherwise it will be true. The integer value of 0 will evaluate to false; however, the STRING value of "0" evaluates to true, as all non-empty strings are true:

{{#and field field}} expr {{else}} expr {{/and}}

Template

Context

Output

1. {{#and Contact.homeAddress Contact.offAddress}}true{{else}}false{{/and}}
2. {{#and Contact.homeAddress emptyString}}true{{else}}false{{/and}}
3. {{#and Contact.homeAddress nullField}}true{{else}}false{{/and}}
4. {{#and Contact.homeAddress zeroValue}}true{{else}}false{{/and}}
5. {{#and Contact.homeAddress zeroString}}true{{else}}false{{/and}}
6. {{#and Contact.homeAddress zeroInteger}}true{{else}}false{{/and}}
{
  "Contact": {
    "homeAddress": "123 Anywhere",
    "offAddress": "789 Somewhere" 
  },
  "emptyString": "",
  "nullfield": null,
  "zeroString": "0",
  "zeroInteger": 0 
}
1. true
2. false
3. false
4. false
5. true
6. false
{{#and legends.unicorns
legends.horses}}
{{legends.unicorns}} -
{{legends.horses}}
{{else}} Not found
{{/and}}
{
  "legends": {
    "unicorns": "11",
    "ponies": "22",
    "horses": "33",
    "total": "66"
  }
}
11-33
{{#and firstName lastName}}
{{firstName}}
{{middleName}}
{{lastName}}
{{else}}Not found
{{/and}}
{
  "fullName": "Hillary Ann Swank",
  "firstName": "Hillary",
  "middleName": "Ann",
  "lastName": "Swank"
}
Hillary Ann
Swank

#compare

The #compare block helper compares two variables using a logical operator.

{{#compare field operator field}} expr {{else}} expr {{/compare}}

The compare helper compares data variables against each other using logical operators. The "else" statement is used to output text if the argument returns a false condition.

Template

{{#compare details.fromState "===" "NE"}}+{{details.qty}}
{{else}}{{details.qty}}{{/compare}}
{{#compare details.fromState "===" "AK"}}TRUE: {{details.qty}}
{{else}}FALSE{{/compare}}

Context

{
  "export": {},
  "details": {
    "fromState": "NE",
    "customerName": "Thomas",
    "customerId": "22222",
    "qty": "3",
    "other": " " 
  }
}

Output

+3

FALSE

The second argument is the arithmetic operator to be used for comparing the two arguments. Optionally, you can also specify the {{else}} expression to render the value when #compare returns FALSE.

In the following example, reversing the operator will change the output to “false.”

Template

{{#compare sample1 ">" sample2}} true {{else}} false {{/compare}}

Context

{
  "sample1": "50",
  "sample2": "100",
  "sample3": "200"
}

Output

true

This example shows a comparison of the quantity on hand against the quantity ordered, and logical output.

Template

{{#compare qty ">=" ordered}}Please ship {{qty}} units
{{else}} do-not-ship{{/compare}}

Context

{
  "state": "VA",
  "name": "Thomas Jefferson",
  "part": "R1",
  "qty": "100",
  "ordered": "100",
  "inventoryOnOrder": "1000",
  "ERP_Item": "kit"
}

Output

Please ship 100 units

This example uses compare to verify a phone number field has exactly 10 digits. If not, the output is ten zeros (0000000000).

Template

{{#compare phone.length "===" 10}}{{else}}0000000000{{/compare}}

Context

{
  "phone": "123456789"
}

Output

0000000000

Logical Operators for #compare

Operator

Description

<

Less than (a < b)

>

Greater than (a > b)

<=

Less than or equal to (a <= b)

>=

Greater than or equal to (a >= b)

==

Equal to (a == b)

If the two compared values are not of the same type (string, boolean, or number), this operator will attempt to convert the values to like types.

===

Strict equal to (a === b)

If the two compared values are not of the same type (string, boolean, or number), this operator will NOT attempt to convert the values to like types. No type conversion is done, and the types must be the same to be considered equal.

!=

Not equal to (a != b)

If the two compared values are not of the same type (string, boolean, or number), this operator will attempt to convert the values to like types.

!==

Strict not equal to (a !== b)

If the two compared values are not of the same type (string, boolean, or number), this operator will NOT attempt to convert the values to like types. No type conversion is done, and the types must be the same to be considered equal.

Note

You can reference literal strings in compare statements by surrounding the literal string in double quotation marks. For example: {{#compare record.Domain "==" "eu.integrator.io"}}

Compare with else

This example shows the #compare block helper with a nested compare expression. The sample compares the quantity order with current inventory levels. It then compares the current inventory levels with items on order. If the order can be successfully filled, the expressions return “Match”. If not, the output returns “Inventory levels too low”.

Template

{{#compare ordered "<=" stockLevel}}Match{{else compare stockLevel "<"
inventoryOnOrder}}Match{{else}}Inventory levels too low{{/compare}}

Context

{
  "state": "NE",
  "name": "Thomas",
  "qty": "100",
  "ordered": "100",
  "stockLevel": "10",
  "inventoryOnOrder": "1000",
  "ERP_Item": "kit"
}

Output

Match

#contains

The #contains block helper parses the name:value specified in the block to check for the presence of a given value. If the value specified is not present, then it prints the {{else}} expression.

{{#contains fieldArray field}} optionalTextIfTrue {{else}} optionalTextIfFalse {{/contains}}

The fieldArray value can be an array name, arrayname.keyname, or a string that will be interpreted as an array.

In the first example, the order.item value is “12345”. The specified value in the #contains block is “5”. Since 5 is a number present in the value, the first expression statement will be displayed. The second example is looking for a “6”. Since 6 is not present, the else statement it output.

Template

Context

Output

{{#contains order.item "5"}}
Sales ID Found!
{{else}}Sales ID Missing!
{{/contains}}
{
  "order": {
    "item": "12345"
  }
}
Sales ID Found!
{{#contains order.item "6"}}
Sales ID Found!
{{else}}Sales ID Missing!
{{/contains}}
{
  "order": {
    "item": "12345"
  }
}
Sales ID Missing!
{{#contains order.sales "2"}}
Sales ID Found!
{{else}}Sales ID Missing!
{{/contains}}
{
  "order": {
    "sales": ["2","3","59","4","9","10","7"]
  }
}
Sales ID Found!

The example below shows an if/then argument against the product and whether or not a product warranty was purchased via an if...else argument against the context fields specified.

Template

{{#contains ERP_Item "kit"}}+1{{else}}None found{{/contains}}
{{#contains warranty "yes"}}Warranty included{{/contains}}

Context

{
  "state": "NE",
  "name": "Thomas",
  "id": "22222",
  "qty": "100",
  "ordered": "100",
  "stockLevel": "100",
  "returned": "100",
  "other": " ",
  "ERP_Item": "kit",
  "warranty": "yes"
}

Output

+1
Warranty included

The example below uses #contains expression nested inside of an if/else expression to set a field to true if another field contains a specific string. In this example, the source_name field contains "3.1415926". If the value for source_name does not contain "3.1415926", the field is set to false.

Template

{{#if source_name}}{{#contains source_name "3.1415926"}}true
{{else}}false{{/contains}}{{/if}}

Context

{
    "source_name": "3.1415926",
    "id": 123,
    "name": "Bob",
    "age": 33
}

Output

true

#each

This helper allows you to iterate over a list. Inside the #each block, you can reference the element to be iterated over.

{{#each field}}{{this}}{{/each}}

This example shows a simple record with names. The {{each}} expression will reference the context while the {{this}} expression will iterate over the array of items in the [people] array.

For the example below, in integrator.io, the [people] array must be referenced as an absolute path in the Resource path field. If the context was an object (name:value pair), then the path would not need to be set.

BlockHelperEach.png

Also in this example, the semicolon and space between the expressions will allow spacing and punctuation between the variables on output.

Template

{{#each people}}{{this}}; {{/each}}

Context

{
  "people": [
    "Bertram Gilfoyle",
    "Erlich Bachman",
    "Jin Yang"
  ]
}

Output

Bertram Gilfoyle; Erlich Bachman; Jin Yang;

This example shows the system iterating over the array in the "field.names" variables.

Template

{{#each fields.names}}{{#each this}} Employee {{@key}}: {{this}}
{{/each}}{{/each}}

Context

{
  "fields": {
    "field": "sample",
    "field2": "row2",
    "rights": [
      "system",
      "admin",
      "editor",
      "contributor",
      "viewer",
      "vendor"
    ],
    "names": [
      {"name1":"Stacy"},
      {"name2":"Lance"},
      {"name3": "Bernice"}
    ]
  }
}

Output

Employee name1: Stacy
Employee name2: Lance
Employee name3: Bernice

When looping through items in #each, you can also reference the current loop index.

Template

System privilege levels: {{@index}}
{{#each fields.rights}}
{{@index}}: {{this}}
{{/each}}

Context

{
  "fields": {
    "field": "sample",
    "field2": "row2",
    "rights": [
      "system", 
      "admin", 
      "editor", 
      "contributor", 
      "viewer", 
      "vendor"
    ],
    "names": [
      {"name1":"Stacy"},
      {"name2":"Lance"},
      {"name3": "Bernice"}
    ]
  }
}

Output

System privilege levels:
0: system
1: admin
2: editor
3: contributor
4: viewer
5: vendor

Additionally for iterating over objects, {{@key}} will reference the current key name. @key will

provide the current index location in an array or the key names in the Context.

Template

{{#each fields.rights}}
  {{@key}}:{{this}};
{{/each}}

Context

{
  "fields": {
    "field": "sample",
    "field2": "row2",
    "rights": [
      "system",
      "admin",
      "editor",
      "contributor",
      "viewer", 
      "vendor"
    ],
    "names": [
      {"name1":"Stacy"},
      {"name2":"Lance"},
      {"name3": "Bernice"}
    ]
  }
}

Output

0:system; 1:admin; 2:editor; 3:contributor; 4:viewer; 5:vendor;

The first and last steps of iteration are noted via the @first and @last variables when iterating over an array. When iterating over an object, only @first is available. Nested #each blocks may access the iteration variables via depth based paths. To access a parent index in a nested #each loop, specify @../index.

The each helper also supports block parameters, allowing for named references anywhere in the block.

Template

{{#each fields.rights}}
  {{@key}}:{{this}};
{{/each}}

Context

{
  "fields": {
    "field": "sample",
    "field2": "row2",
    "rights": [
      "system",
      "admin",
      "editor",
      "contributor",
      "viewer",
      "vendor"
    ],
    "names": [
      {"name1":"Stacy"},
      {"name2":"Lance"},
      {"name3": "Bernice"}
    ]
  }
}

Output

0:system; 1:admin; 2:editor; 3:contributor; 4:viewer; 5:vendor;

To create a list or convert data based on index location in a record, you can declare an |item| using vertical bars (pipe character), then entering the characters by their respective index locations (where 0=first character).

Template

{{#each inventoryItems as |item|}}
  {{item.[0]}}: {{item.[10]}}
{{/each}}

Context

{
  "inventoryItems": {
    "X": "1001 text a",
    "Y": "2002 text b",
    "Z": "3003 text c"
  }
}

Output

1: a
2: b
3: c

#if...else

The #if _else helper allows an if/then argument.

{{#if field}}expr{{else}}expr{{/if}}

If the argument in the {{#if field}} is true, then it prints the value from the context. If the argument is false (either undefined, null, " ", 0, or [ ] ), then the block prints the else condition.

Important

Do not use spaces in this expression.

If Else logical operators

The following logical operators may be used for building an argument or placing arguments inside expressions.

if

If a specified condition is true, this specifies a block of code to be executed

If the condition is false, another block of code can be executed.

{{#if data.name}}{{data.name}}{{/if}}

if...else

This statement is a part of JavaScript's "Conditional" Statements, which are used to perform different actions based on different conditions, and will execute a block of code if a specified condition is true.

{{#if Name}}{{Name}}{{else}}{{/if}}

else

Specifies a block of code to be executed if the same condition is false.

else if

Specifies a new condition to test if the first condition is false.

compare

Compares two values using logical operators.

{{#compare field operator field}} expr {{else}} expr {{/compare}}

each

{{#each data.identity-profiles}} {{vid}} {{/each}}

if...compare

{{#if data.name}}{{#compare data.name "!="
""}}{{data.name}}{{else}}{{/compare}}{{/if}}

#ifEven

This argument checks to see if a given value is an even number.

{{#ifEven field}} expr {{else}} expr {{/ifEven}}

If the argument results in an even number (true), the value prints to output. If the argument results in an odd number (false), the {{else}} expression displays. A blank expr field prints the value unless text is specified, as shown below.

Template

Context

Output

{{#ifEven orders.item1}}
  {{orders.item1}}
{{else}}
  Odd Value
{{/ifEven}}
{
  "orders": {
    "item1": "2",
    "item2": "5",
    "item3": "8"
  }
}  
2
{{#ifEven orders.item2}}
  The even number value is {{orders.item2}}
{{else}}
  Odd number value
{{/ifEven}}
Odd number value
{{#ifEven orders.item3}}
  The even number value is {{orders.item3}}
{{else}}
    Odd number value
{{/ifEven}}
The even number value is 8

#neither

This helper is used for building true/false arguments.

{{#neither field field}} expr {{else}} expr {{/neither}}
  • If both parameters are equal to false, the first expression displays.

  • If one or both are equal to true, the {{else}} expression statement displays.

In this example, both the values in the Context are blank /null (which makes the argument true), so the first expression is printed to output.

Template

{{#neither item1 item2}}
  Values are absent for the specified parameters.
{{else}}
  Only one of the parameters has a value.
{{/neither}}

Context

{
  "item1": "",
  "item2": ""
}

Output

Values are absent for the specified parameters.

In this example, only one of the Context variables is blank, so the argument will pass the {{else}} statement to the output.

Template

{{#neither item1 item2}}
  Values are absent for at least one of the specified parameters.
{{else}}
  Only one of the parameters has a value.
{{/neither}}

Context

{
  "item1": "",
  "item2": "5"
}

Output

Only one of the parameters has a value.

#or

This helper creates an all-or-nothing argument. It prints the first expression if the argument is true, and the {{else}} expression if the argument is false.

{{#or field field}} expr {{else}} expr {{/or}}

Template

Context

Output

{{#or item1 item2}}
  One or both fields have a data value
{{else}}
  Neither field has a data value
{{/or}} 
{
  "item1": "100",
  "item2": "15000"
}
One or both fields have a data value.
{
  "item1": "",
  "item2": ""
}
Neither field has a data value.

#unless

The #unless helper is the inverse argument of the #if block helper. The #unless block renders if the #unless expression returns a false value.

{{#unless field}} expr {{else}} expr {{/unless}}

Template

Context

Output

{{#unless contact.phone}}
  Phone number missing
{{else}}
  Contact phone number
{{contact.phone}}
{{/unless}} 
{
  "contact": {
    "phone": "310-555-1234",
    "street": "streetName",
    "address": "streetAddress"
  }
}
Contact phone number is:
310-555-1234
{
  "contact": {
    "street": "streetName",
    "address": "streetAddress"
  }
}
Phone number missing

#with

The #with helper demonstrates how to pass a parameter to your helper. When a parameter calls a helper, it is invoked with whatever context the template passed in. This allows access to nested objects in the context without having to repeatedly type the parent name in each expression.

Template

{{#with library}}{{title}} on "{{album}}" by {{artist}} {{/with}}

Context

{
  "library": {
    "album": "The Sound",
    "title": "Danube Incident",
    "artist": "Lalo Schifrin"
  }
}

Output

Danube Incident on "The Sound" by Lalo Schifrin

The with helper passes a parameter to a helper.

{{#with field}} {{field1}} {{field2}} {{/with}}

When a parameter calls the helper, it invokes the context from the template.

Template

The author{{#with author}} {{firstName}} {{lastName}}{{/with}}

Context

{
  "title": "A Tale of Two Cities",
  "author": {
    "firstName": "Charles",
    "lastName": "Dickens"
  }
}

Output

Output The author Charles Dickens

Nesting block helpers

The following expressions describe the expression format and samples for block helpers. Variables and “hard-coded” values may be nested and referenced.

Template

{{#if contact.phone}}{{contact.phone}}
{{else}} Phone number not found
{{/if}}

Context

{
  "contact": {
    "name": "Jack Parsons Laboratory",
    "phone": "310-555-1234"
  }
}

Output

310-555-1234

Block helpers may also be nested, as shown below.

Template

{{#compare customer1 "==" "2"}}
{{#compare customer2 "==" "5"}}
  True
{{else}}
  False
{{/compare}}{{else}}
  False
{{/compare}}

Context

{
  "customer1": "2",
  "customer2": "5"
}

Output

True

Raw blocks

Raw blocks are virtually the same as block helpers; however, child content is treated as a literal string.

Template

Context

Output

{{{{name}}}}
  {{Samantha}}
{{{{/name}}}}
{

}
{{Samantha}}

data variables

root

Reference the @root data variable to access the root element properties while you iterate in the context of any nested or child elements. The following scenarios illustrate @root with sample JSON.

Template

Context

Output

{{@root.title}}
{
  "title": "My New Post",
  "body": "This is my first post!",
  "array": [1,2,3,4],
  "message": "This is the message."
}
My New Post
{{#each array}}{{@root.title}}
{{/each}}
{
  "title": "My New Post",
  "body": "This is my first post!",
  "array": [1,2,3,4],
  "message": "This is the message."
}
My New Post
My New Post
My New Post
My New Post
 {{@root.child.childTitle}}
{
  "title": "My New Post",
  "body": "This is my first post!",
  "array": [1,2,3,4],
  "message": "This is the message.",
  "child": {
    "childTitle": "Child Title",
    "childBody": "Child Body"
  }
}
Child Title

key

This data variable provides the current index location in an array or the key names in the context. The key is the index value of the array. When iterating through values in an array, the output always starts with 0.

Template

Context

Output

{{#each array}}
{{@key}}
{{/each}}
{
  "title": "My New Post",
  "body": "This is my first post!",
  "array": [1,2,3,4],
  "message": "This is the message.",
  "child": {
    "childTitle": "Child Title",
    "childBody": "Child Body"
  }
}
0 1 2 3
{{#each array}}
{{@key}}
{{/each}}
{
  "title": "My New Post",
  "body": "This is my first post!",
  "array": ["one","two","three","four"],
  "message": "This is the message.",
  "child": {
    "childTitle": "Child Title",
    "childBody": "Child Body"
  }
}
0 1 2 3
{{#each @root.child}}
{{@key}}
{{/each}}
{
  "title": "My New Post",
  "body": "This is my first post!",
  "array": [1,2,3,4],
  "message": "This is the message.",
  "child": {
    "childTitle": "Child Title",
    "childBody": "Child Body"
  }
}
childTitle
childBody

{{#each @root}}
{{@key}}
{{/each}}
{
  "title": "My New Post",
  "body": "This is my first post!",
  "array": [1,2,3,4],
  "message": "This is the message.",
  "child": {
    "childTitle": "Child Title",
    "childBody": "Child Body"
  }
}
title body array
message child

index

This data variable gives you the current index in an array iteration or in a JSON iteration in the context of #each.

Template

Context

Output

{{#each @root.child}}
{{@index}}
{{/each}}
{
  "title": "My New Post",
  "body": "This is my first post!",
  "array": [1,2,3,4],
  "message": "This is the message.",
  "child": {
    "childTitle": "Child Title",
    "childBody": "Child Body"
  }
}
0 1
{{#each @root.people}}
{{@index}}
{{/each}}
{
  "people": [
    "Bertram Gilfoyle",
    "Erlich Bachman",
    "Jin Yang"
  ]
}
0 1 2

first

This data variable returns true for the first element of an array or an object. When iterating through values in an array, the output always starts with 0.

Template

Context

Output

{{#each @root.child}}
{{#if @first}}
{{@key}}
{{/if}}
{{/each}}
{
  "title": "My New Post",
  "body": "This is my first post!",
  "array": [1,2,3,4],
  "message": "This is the message.",
  "child": {
    "childTitle": "Child Title",
    "childBody": "Child Body"
  }
}
childTitle
{{#each array}}
{{#if @first}}
{{@key}}
{{/if}}
{{/each}}
{
  "title": "My New Post",
  "body": "This is my first post!",
  "array": [1,2,3,4],
  "message": "This is the message.",
  "child": {
    "childTitle": "Child Title",
    "childBody": "Child Body"
  }
}
0
{{#each array}}
{{#if @first}}
{{@key}}
{{/if}}
{{/each}}
{
  "title": "My New Post",
  "body": "This is my first post!",
  "array": ["apple","orange","pear","banana"],
  "message": "This is the message.",
  "child": {
    "childTitle": "Child Title",
    "childBody": "Child Body"
  }
}
0

last

This data variable returns true for the last element of an array or an object. When iterating through values in an array, the output always starts with 0. In a nested loop, refer to the immediate parent with the index @../last, and so on.

Template

Context

Output

{{#each @root.child}}
{{#if @last}}
{{@key}}
{{/if}}
{{/each}}
{
  "title": "My New Post",
  "body": "This is my first post!",
  "array": [1,2,3,4],
  "message": "This is the message.",
  "child": {
    "childTitle": "Child Title",
    "childBody": "Child Body"
  }
}
childBody
{{#each array}}
{{#if @last}}
{{@key}}
{{/if}}
{{/each}}
{
  "title": "My New Post",
  "body": "This is my first post!",
  "array": [1,2,3,4],
  "message": "This is the message.",
  "child": {
    "childTitle": "Child Title",
    "childBody": "Child Body"
  }
}
3
{{#each array}}
{{#if @last}}
{{@key}}
{{/if}}
{{/each}}
{
  "title": "My New Post",
  "body": "This is my first post!",
  "array": [
    "apple",
    "orange",
    "pear",
    "banana"
  ],
  "message": "This is the message.",
  "child": {
    "childTitle": "Child Title",
    "childBody": "Child Body"
  }
}
3

this

The this keyword refers to different objects, depending on how it’s invoked (used or called).

You can use the this expression in handlebars to reference the current context. Within a block helper, this refers to the element being iterated over. While iterating an object, this refers to the complete object. While iterating an array, this refers to a complete array. We have to use {{#each this}} to refer to individual elements in an array.

Template

Context

Output

[
  {{#with data}}
    {{#each this}}
    {{#if @index}}, {{/if}}
    {
             "firstName" : {{this.name}},
      {{#each this}}
        “{{@key}}”: “{{this}}”
      {{/each}}
    }
    {{/each}}
  {{/with}}
]
{
  "data": [
    {
      "name": "John",
      "id": 1
    },
    {
      "name": "Leslie",
      "id": 2
    }
  ]
}
          [
    {
      "firstName": "John",
      "Name": "John",
      "id": 1
    },
    {
      "firstName": "Leslie",
      "name": "Leslie",
      "id": 2
    }
  ]
       

This example shows a simple dataset with two names. The first {{#each this}} references the objects in the data array. So, in this case, we’re referring to each object in the array.

{
  "data": [
    {
      "name": "John",
      "id": 1
    },
    {
      "name": "Leslie",
      "id": 2
    }
  ]
}

The second use of {{#each this}} references each element of the object. That would be the key: value pairs in each object.

{
  "data": [
    {
      "name": "John",
      "id": 1
    },
    {
      "name": "Leslie",
      "id": 2
    }
  ]
}

The third use of {{this}} references the value of the key: value pair.

{
  "data": [
    {
      "name": "John" ,
      "id":  1 
    },
    {
      "name":  "Leslie" ,
      "id":  2
    }
  ]
}

So, the final output would be

[
    {
      "name": "John",
      "id": 1
    },
    {
      "name": "Leslie",
      "id": 2
    }
  ]

length

Counts the length of a given string for use in other functions.

This example counts the length of the state field. If the length is exactly two characters, integrator.io capitalizes the output. If the length is not exactly two characters, the output is "Bad state value".

Template

{{#compare state.length "===" 2}}{{uppercase state}}{{else}}Bad state value{{/compare}}

Context

{
  "state": "ill"
}
{
  "state": "il"
}

Output

Bad state value
IL

This example uses length with the compare handlebar to verify a phone number field has exactly 10 digits. If not, the output is ten zeros (0000000000).

Template

{{#compare phone.length "===" 10}}{{phone}}{{else}}0000000000{{/compare}}

Context

{
  "phone": "123456789"
}

Output

0000000000
Was this article helpful?
5 out of 6 found this helpful

Comments

70 comments
Date Votes
  • Thanks, Stephen, it worked. will post if I have any issues.

     
    0
  • I have a use case where I need to define a JSON array by nested enumeration of hierarchical source data. The challenge is how to avoid the trailing comma for the last element.

    [
    3,
    6, <-- Err!
    ]

    Because the source data is hierarchical, I can't make the comma conditional on the outer #each and likewise I can't make it conditional on the nested, inner #each; I need to consider BOTH of them when determining if a comma should be created or not.

    Were it not for the inability to access the @last variable in the parent scope, something like this would work perfect:

    [
    {{#each outer_array}}
    {
    "name": "foo {{{name}}}"
    },{{#each inner_array}}{
    "size": {{{size}}}
    }{{#unless @last && ../@last}},{{/unless}}
    {{/each}}
    {{/each}}
    ]

    The key is checking for the end of the outer and inner loops.

    {{#unless @last && ../@last}},{{/unless}}

    The problem is, ../@last doesn't work. I can't find any way to access @ variables from the inner loop scope.


    UPDATED 6/17/2021 –
    Solved, self-answered:

    The @ symbol precedes the path: 

    {{{@../index}}}
    • Celigo action item: update @last with example for nested loops
    0
  • Hi Dominik Antalík,

    Thanks for letting us know about your use case. I apologize for the late response - I missed this comment coming in. Have you gotten this resolved yet? I'm checking with our handlebars experts.

    0
  • Hi Dominik Antalík,

    We do not support registering custom helpers at this time. If you could enter an enhancement request, we can gauge whether to add this to the roadmap. Thanks!

    0
  • HI,

    If we have an array of objects:

    [{amount: 10,...}, {amount:20,...}, {amount:20,...}]

    How can we add all amount field from each object then multiply by 100 using handlebar expressions?

    0
  • Hi, A Arora. Thanks for contacting us, and sorry for the delay over the long U.S. holiday weekend. 

    A few suggestions are posted in a related Community thread. The easiest, according to the in-house experts would be to transform the data structure to flatten the amounts into a single array. Then, you can call sum as follows:

    {{multiply (sum amount)  100}}

    You should consider the other solutions in the linked post if you needed to maintain your present record structure for downstream processing. 

    0
  • timestamp should be updated to indicate that when no format is supplied it will return an ISO8601 string (what I wanted). I had to go dig through moment.js docs to determine that for sure.

    0
  • On the dateFormat documentation for i/pformat:

    This field is the date object referenced in the Context.

    Whaaaaa? ;)

     

    0
  • Steve Klett 

    Thanks for this information regarding the default timestamp format. I've revised the article to reflect your research. 

    For the dateFormat question, we use the term "Context" to refer to the source data from the incoming record to be interpreted by the handlebars expression, so the following statement:

    "This field is the date object referenced in the Context."

    a few lines down from that we state:

    "Input format (i/pformat) is where you define the "input" format contained in the Context file"

    So if you have an incoming record with a specific format, you would specify the incoming format as the i/pformat. You would then use the o/pformat to define the format that you want to convert the incoming format into. 

    Does that make more sense? Please email me at tom.santiago@celigo.com if you'd like to further discuss how I can improve the documentation so that it's less confusing.

    0
  • Hi,

    The regexMatch documentation doesn't make any sense to me. The property description for regex is wrong:

    regex: the new value which will replace the existing value.

    The first two samples seem to have the syntax for regexReplace, not to mention the second one is maybe not a great example to replace a value with the same value. Anyway, I had to spend quite a bit of time looking at this trying to figure out if I'm dense and need a break of if the docs are totally confusing me.

    0
  • Hi,
    I have this to get the current date
                     {{dateFormat "YYYY-MM-DD HH:mm" date}}
    I'd like to add the timezone (Europe/London).

    I tried this {{dateFormat "YYYY-MM-DD HH:mm" date "YYYY-MM-DD[T]hh:mm:ss.sss[Z]" "Europe/London"}} but I got the error

    "Could not compile handle bar \{{dateFormat "YYYY-MM-DD HH:mm" date "YYYY-MM-DD[T]hh:mm:ss.sss[Z]" "Europe/London"}}\" because \"handlebars Helper {{dateFormat}} expects date argument when you have i/p date format\" .Please correct and retry"

    How can I add the timezone when getting the current date?

    Thank you.
    Josy

    0
  • Hi Josyrley de Almeida -
    I checked in with one of our handlebars gurus and this was his response:
    If you don't specify an input date format (it's often not required), you can use a blank string for it when adding timezone. In a handlebar w/out timezone, the blank string is assumed.

    {{dateFormat "YYYY-MM-DD HH:mm" date "" "Europe/London"}}

    In order for

    {{dateFormat "YYYY-MM-DD HH:mm" date "YYYY-MM-DD[T]hh:mm:ss.sss[Z]" "Europe/London"}} 

    to work, there would need to be a source field "date" in YYYY-MM-DD[T]hh:mm:ss.sss[Z]" format. Also, I don't think brackets around the [T] and [Z] are correct, even if there is that field.

    YYYY-MM-DDTHH:mm:ssZ

    If you need any further assistance, please sign up for an office hours session. Thanks!

    0
  • What is the proper syntax for the {{else_if}} block?

    0
  • Hi Stephen Lemp,

    Here is an example of  {{else if}}:

    {{#if name}}{{name}}{{else if test}}Steve{{else}}Kat{{/if}}

    In the above example, if the name field exists, the value of name prints.

    If the name field does not exist {{else if}}, and a field named test exists, then Steve prints.

    If neither name nor test fields exist, Kat prints.

    We'll revise this section of the article for clarity soon.

    0
  • Any recommendations on how to dateAdd to get the previous month?  1 month previous to today that is.

    All we really care about is 'MON-YYYY' format.

    Thanks!

    0
  • Hi Brian,

    Assuming that your input date is something like "2021-12", the following should work:

    {{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Jan"}}{{dateFormat "[Dec]-YYYY" (dateAdd [Order Date] "-31556952000")}}{{else}}{{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Feb"}}{{dateFormat "[Jan]-YYYY" [Order Date]}}{{else}}{{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Mar"}}{{dateFormat "[Feb]-YYYY" [Order Date]}}{{else}}{{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Apr"}}{{dateFormat "[Mar]-YYYY" [Order Date]}}{{else}}{{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "May"}}{{dateFormat "[Apr]-YYYY" [Order Date]}}{{else}}{{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Jun"}}{{dateFormat "[May]-YYYY" [Order Date]}}{{else}}{{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Jul"}}{{dateFormat "[Jun]-YYYY" [Order Date]}}{{else}}{{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Aug"}}{{dateFormat "[Jul]-YYYY" [Order Date]}}{{else}}{{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Sep"}}{{dateFormat "[Aug]-YYYY" [Order Date]}}{{else}}{{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Oct"}}{{dateFormat "[Sep]-YYYY" [Order Date]}}{{else}}{{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Nov"}}{{dateFormat "[Oct]-YYYY" [Order Date]}}{{else}}{{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Dec"}}{{dateFormat "[Nov]-YYYY" [Order Date]}}{{else}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}

    If your input date is in a different format, you'll just need to change "YYYY-MM" (the input dateFormat) to the proper format.

    Additionally, the above assumes that the field is named "Order Date" in your source data.

    Here's a version of the above code block that should be a bit easier to read, but you'll want to use the one above in your integration:

    {{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Jan"}}
    {{dateFormat "[Dec]-YYYY" (dateAdd [Order Date] "-31556952000")}}
    {{else}}
    {{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Feb"}}
    {{dateFormat "[Jan]-YYYY" [Order Date]}}
    {{else}}
    {{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Mar"}}
    {{dateFormat "[Feb]-YYYY" [Order Date]}}
    {{else}}
    {{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Apr"}}
    {{dateFormat "[Mar]-YYYY" [Order Date]}}
    {{else}}
    {{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "May"}}
    {{dateFormat "[Apr]-YYYY" [Order Date]}}
    {{else}}
    {{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Jun"}}
    {{dateFormat "[May]-YYYY" [Order Date]}}
    {{else}}
    {{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Jul"}}
    {{dateFormat "[Jun]-YYYY" [Order Date]}}
    {{else}}
    {{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Aug"}}
    {{dateFormat "[Jul]-YYYY" [Order Date]}}
    {{else}}
    {{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Sep"}}
    {{dateFormat "[Aug]-YYYY" [Order Date]}}
    {{else}}
    {{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Oct"}}
    {{dateFormat "[Sep]-YYYY" [Order Date]}}
    {{else}}
    {{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Nov"}}
    {{dateFormat "[Oct]-YYYY" [Order Date]}}
    {{else}}
    {{#contains (dateFormat "YYYY-MMM" [Order Date] "YYYY-MM") "Dec"}}
    {{dateFormat "[Nov]-YYYY" [Order Date]}}
    {{else}}
    {{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}{{/contains}}}

    Dan

    0
  • Thanks @....  Looks like that formula is exceeding the maximum byte size of the FILE NAME field though.  We're looking to use this handlebar expression to provide the file name in an FTP operation.

    No way to actually addMonth ?  

    Moment.js does offer a way to addMonth.  And from what I understand Celigo uses moment.js on the backend.

    No way to make an addMonth call in handlebars at all huh?

    Thanks for your input on this!

     

    0
  • Hi Brian,

    Ah, I didn't realize this was for an FTP filename.

    We do not have a handlebar helper for addMonth, however, please feel free to file an enhancement request here.

    An alternative would be the following:

    {{dateFormat "MMM-YYYY" (dateAdd [Order Date] "-2592000000")}}

    The above can be inaccurate, as it subtracts 2592000000 milliseconds (30 days) from the given timestamp. For instance, if the "Order Date" is 2021-03-01, the output would be "Jan-2021, since February only has 28 (or 29) days.

    Another alternative would be if you can include the date with the previous month in your export data, you can reference this field in your filename.

    Best Regards,
    Dan

    0
  • Hi Brian,

    I had a little more time to clean up that first handlebar helper and created one that uses the current timestamp then changes that value to the prior month (and year, for dates in January). This should do the trick:

    {{#contains (dateFormat "MMM") "Jan"}}{{dateFormat "[Dec]-YYYY" (dateAdd "-31556952000")}}{{else contains (dateFormat "MMM") "Feb"}}{{dateFormat "[Jan]-YYYY"}}{{else contains (dateFormat "MMM") "Mar"}}{{dateFormat "[Feb]-YYYY"}}{{else contains (dateFormat "MMM") "Apr"}}{{dateFormat "[Mar]-YYYY"}}{{else contains (dateFormat "MMM") "May"}}{{dateFormat "[Apr]-YYYY"}}{{else contains (dateFormat "MMM") "Jun"}}{{dateFormat "[May]-YYYY"}}{{else contains (dateFormat "MMM") "Jul"}}{{dateFormat "[Jun]-YYYY"}}{{else contains (dateFormat "MMM") "Aug"}}{{dateFormat "[Jul]-YYYY"}}{{else contains (dateFormat "MMM") "Sep"}}{{dateFormat "[Aug]-YYYY"}}{{else contains (dateFormat "MMM") "Oct"}}{{dateFormat "[Sep]-YYYY"}}{{else contains (dateFormat "MMM") "Nov"}}{{dateFormat "[Oct]-YYYY"}}{{else contains (dateFormat "MMM") "Dec"}}{{dateFormat "[Nov]-YYYY"}}{{/contains}}

    Here it is in action:


    Dan

    0
  • Hi Brian,

    One of our engineers, Lucian Hymer, came up with a more elegant solution:

    {{#compare (dateFormat "MM") "==" 1}}Dec-{{subtract (dateFormat "YYYY") 1}}{{else}}{{dateFormat "MMM" (subtract (dateFormat "MM") "1") "MM"}}-{{dateFormat "YYYY"}}{{/compare}}

    This will give the same output as well:

    Dan

    0
  • Hey Dan, awesome!  This is great and is working wonderfully!  Really appreciate this quick response and great solution.  Thanks Dan!

    0
  • This may be a small thing, but would it be possible to add a "Back To Top" button? Often times Im here and looking something up,then need to go back up to the top to look at another function. I know I can click the "Back" button, but thats so far up on the screen!! (im joking about that). Just one of those simple quality of life things for those like me that have to spend time here

    0
  • Hi Mel Haynes, Jr.,

    We are considering some solutions to the problem you've raised including a back to top button or a side nav menu, but we haven't yet confirmed upcoming revisions to our knowledgebase navigation strategy. We will notify everyone when such improvements are rolled out. One trick I rely on at the moment is right-clicking the link and opening it in a new tab to create a browser instance open to each handlebars expression I need to reference. 

    Tom

    0
  • Mel Haynes, Jr. CTRL+HOME will jump back to the top.

    1
  • Thanks for the tip, Steve Klett. I added that trick to the top of this article.

    Tom

    0
  • I'm trying to use the {{capitalizeAll Field}} expression to capitalize First and Last Names from on online form to normalize the data before it is imported in to NetSuite and it's not working. 

    Template - {{capitalizeAll 86}}

    Context - '86' is the Field ID on the form for First Name

    Output - ""

    Without the expression I get the name imported exactly as it was input. "FIRST name = FIRST name" and I would like to get "First Name" But with the expression no data comes through and I get an error stating missing data for import field "First name"

    I've tried {{capitalizeAll ID.86}} and other versions showing the path but the error comes back:

    Message: Could not compile handle bar "{{capitalizeAll ID.86}}" because "Parse error on line 1:
    {{capitalizeAll ID.86}}
    -------------------^
    Expecting 'ID', got 'NUMBER'" .Please correct and retry.

    What am I missing?

    0
  • Hi AJ. Enclose your field name in square brackets.  Use [86] or [ID.86]

    0
  • That was very simple. I'm annoyed at myself for not having tried that. Thanks

    0
  • Please add a pad() helper like freemarker has:

    https://freemarker.apache.org/docs/ref_builtins_string.html#ref_builtin_left_pad

    This is essential for fixed width templates (e.g., some EDI docs)

     

    0
  • Thanks, Steve Klett. I've added your insight to Product Board partner and customer request. 

    0

Please sign in to leave a comment.