Handlebars

Handlebars is a JavaScript library used for creating dynamic HTML templates.

It allows you to define templates with placeholders, and these placeholders are replaced with data when the template is triggered with the information sent in the payload.

Handlebars within Fyno support features like conditional operations, loops, partial searches, and custom helpers, making it a very cool tool to use when creating your templates.

Handlebars in Fyno's Templates

To understand how handlebars work, we first need to establish a sample payload, based off which the Handlebars function and applicability can be demonstrated.

{
    "members": [
        {
            "first_name": "Ashwin",
            "last_name": "Agarwal",
            "city": ""
        }
    ],
    "investments": [
        {
            "amount": 10,
            "company": "L&T"
        },
        {
            "amount": 20
        }
    ],
    "companies": {
        "L&T": "India",
        "Apple": "USA"
    },
    "user_type": "pro",
    "period": {
        "start": "2023-10-01",
        "end": "2023-10-03"
    },
    "classification": [
        "active",
        "pro"
    ]
}

Fyno has default as well as custom handlebars that you can use in your templates. Let's have a look at what these are and how to use them using the above payload and data as example responses.

🚧

Double Quotes within Handlebars {{" "}} may break your templates!

Double quote may break your syntax in HBS, especially in emails! And nobody wants that!

For example: Use {{math number1 '+' number2}} instead of {{math number1 "+" number2}}

Use single quotes {{' '}} instead! 😎

PurposeSyntaxExample
To access placeholder values{{key}}{{user_type}}

Output:

pro
To access values of an object{{key.subkey}}{{period.start}} to {{period.end}}

Output:

2023-10-01 to 2023-10-03
To access object values from an array{{key.index.subkey}}{{members.0.first_name}}

Output:

Ashwin
To access values from an array{{key.[index]}}{{classification.[0]}}

Output:
active
To avoid escaping the values{{{key}}}{{{investments.0.company}}}
Note: If you use double-brackets instead of triple, L&T will show as L&T

Output:

L&T
To get length of an array{{key.length}}User made {{investments.length}} investments

Output:
User made 2 investments
To check if variable exists{{#if variable}} Content Here {{else if variable}} Content Here {{else}} Content Here {{/if}}{{#if members.0.city}} City available for member 1 and may be member 2 {{else if members.1.city}} City available for member 2 only {{else}} City not available for member 1 and 2 {{/if}}

Output:

City available for member 1 and may be member 2
Approach 1: To check if variable equals a certain value{{#if (eq variable 'value')}}{{else if (eq variable 'value')}}{{/if}}{{#if (eq investments.0.company 'L&T')}}First investment was L&T {{else if (eq investments.0.company 'Apple')}}First investment was Apple {{else}}First investment was neither Apple nor L&T{{/if}}

Output:
First investment was L&T
Approach 2: To check if variable equals a certain value{{#ifEquals variable 'value'}} {{else ifEquals variable 'value'}} {{else}} {{/ifEquals}}{{#ifEquals investments.0.company 'L&T'}} First investment was L&T {{else ifEquals investments.0.company 'Apple'}} First investment was Apple {{else}} First investment was neither Apple nor L&T {{/ifEquals}}

Output:

First investment was L&T
To check if multiple variables equal a certain value (AND and OR options){{#if (and/or (eq/ne/lt/gt/lte/gte variable 'value') (eq/ne/lt/gt/lte/gte variable 'value'))}} {{else}} {{/if}}{{#if (or (eq investments.0.company 'L&T') (eq investments.0.company 'Apple'))}} First investment is either L&T OR Apple {{/if}}

{{#if (and (eq investments.0.company 'L&T') (gt investments.0.amount 5) )}} First investment is L&T and investment amount is greater than 5 {{/if}}

{{#if (and (ne user_type 'pro') (gte investments.0.amount 10) )}} User is not pro but first investment is greater than or equal to 10 {{else if (and (eq user_type 'pro') (lt investments.0.amount 10) )}} User type is pro but first investment is less than 10 {{else if (and (eq user_type 'pro') (eq investments.0.amount 10) )}} User type is pro and first investment is equal to 10 {{/if}}

Output:

First investment is either L&T OR Apple

First Intestment is L&T and investment amount is greater than 5

User type is pro and first investment is equal to 10
To check if variable equals a regular expression{{#ifMatches variable 'regex'}} {{else ifMatches variable 'regex'}} {{else}} {{/ifMatches}}{{#ifMatches members.0.last_name 'Aga\*'}} Matched {{else}} Not matched {{/ifMatches}}

Output:

Matched
To check if string starts with certain characters{{#ifStartsWith variable 'value'}} {{else ifStartsWith variable 'value'}} {{else}} {{/ifStartsWith}}{{#ifStartsWith members.0.first_name 'A'}} Name starts with A {{else}} Name does not start with A {{/ifStartsWith}}

Output:

Name starts with A
To use OR operator between two variables{{#compare var1 'or' var2}} {{else compare var1 'or' var2}} {{/compare}}{{#compare investments.0.amount 'or' investments.1.amount}} Invested at least once {{else}} No investment made {{/compare}}

Output:

Invested at least once
To use AND operator between two variables{{#compare var1 'and' var2}} {{else compare var1 'and' var2}} {{/compare}}{{#compare investments.0.amount 'and' investments.1.amount}} Invested at least twice {{else}} One or fewer investments made {{/compare}}
Output:

Invested at least twice
To use a specified default value if the actual value does not exist (or is null){{default variable 'value'}}{{default members.0.city 'Bangalore'}}

Output:

Bangalore
To sum two numbers{{math number1 '+' number2}}{{math investments.0.amount '+' investments.1.amount}}

Output:

30
To subtract two numbers{{math number1 '-' number2}}{{math investments.1.amount '-' investments.0.amount}}

Output:

10
To multiply two numbers{{math number1 '*' number2}}{{math investments.0.amount '*' investments.1.amount}}

Output:

200
To divide numbers{{math number1 '/' number2}}{{math investments.0.amount '/' investments.1.amount}}

Output:

0.5
To perform modulo{{math number1 '%' number2}}{{math investments.0.amount '%' investments.1.amount}}

Output:

10
To round numbers{{math number 'round' decimal_places}}{{math investments.0.amount 'round' 2}} {{math investments.0.amount 'round'}}

Output:

10.00

10
To check for negative condition (show something only if key doesn't exist){{#unless key}} {{/unless}}{{#unless investments}} Investments were not made! {{else}} Investments were made! {{/unless}}

Output:

Investments were made!
To iterate over a list/array{{#each key}} {{this.subkey}} {{/each}}{{#each investments}} {{math @index '+' 1}}. {{{default this.company 'Not known'}}} - ${{this.amount}} {{else}} No investments were made! {{/each}}

Output:

1. L&T - $10

2. Not known - $20
To use combination of conditions and nesting (advanced){{#if variable}} {{else ifEquals variable 'value'}} {{else ifMatches variable 'regex'}} {{else ifStartsWith variable 'value'}} {{else if (eq var1 var2)}} {{/if}}{{#if investments}} {{#ifEquals investments.0.company 'Apple'}} Invested in Apple Inc! {{else ifMatches investments.0.company 'Amazon\*'}} Invested in Amazon ventures! {{else ifStartsWith investments.0.company 'Microsoft'}} Invested in Microsoft! {{else if (eq investments.0.company 'L&T')}} Invested in Larsen & Toubro! {{/ifEquals}} {{else}} No investments were made! {{/if}}

Output:

Invested in Larsen & Toubro!
To lookup values and use them in placeholders (advanced){{#each iterate_key}} {{subkey}} {{lookup ../key [subkey]}} {{/each}}{{#each investments as | investment |}} {{#if company}} {{{company}}} is in {{lookup ../companies [company]}} {{/if}} {{/each}}
Output:

L&T is in India
To split variables and get value at index{{split variable_name 'delimiter' index}}{{split period.start '-' -1}}/{{split period.start '-' 1}}/{{split period.start '-' 0}} {{split period.end '-' -1}}/{{split period.end '-' 1}}/{{split period.end '-' 0}}

Output:

01/10/2023

03/10/2023
To split variables and loop on it{{#each (split variable_name 'delimiter')}} {{this}} {{/each}}{{#each (split period.start '-')}} {{this}} {{/each}}

Output:

2023

10

01
To check if timestamp equals to today or yesterday or tomorrow{{relativeDay timestamp_with_timezone}}{{relativeDay '2023-10-25T14:30:00+05:30'}}
{{relativeDay '2023-10-26T14:30:00+05:30'}}
{{relativeDay '2023-10-24T14:30:00+05:30'}}
{{relativeDay period.start}}
{{#ifEquals (relativeDay '2023-12-19T14:30:00+05:30') "today"}}The date is today!{{else}}The date is not today!{{/ifEquals}}

Output:
today
tomorrow
yesterday
before
The date is today!
To check difference between two dates (in seconds, minutes, days, hours, month, hours, etc) {{dateDiff timestamp1_with_timezone timestamp2_with_timezone 'ms / seconds / minutes / hours / days / weeks / months / years'}}

Note: The date and time must be in RFC-3339, ISO_8601 or the helper will return NaN
{{dateDiff '2023-12-01T14:30:00+05:30' '2023-12-19T14:30:00+05:30' 'ms'}} ms
{{dateDiff '2023-12-01T14:30:00+05:30' '2023-12-19T14:30:00+05:30' 'seconds'}} secs
{{dateDiff '2023-12-01T14:30:00+05:30' '2023-12-19T14:30:00+05:30' 'minutes'}} mins
{{dateDiff '2023-12-01T14:30:00+05:30' '2023-12-19T14:30:00+05:30' 'hours'}} hours
{{dateDiff '2023-12-01T14:30:00+05:30' '2023-12-19T14:30:00+05:30' 'days'}} days
{{dateDiff '2023-12-01T14:30:00+05:30' '2023-12-19T14:30:00+05:30' 'weeks'}} weeks
{{dateDiff '2023-12-01T14:30:00+05:30' '2023-12-19T14:30:00+05:30' 'months'}} months
{{dateDiff '2023-12-01T14:30:00+05:30' '2023-12-19T14:30:00+05:30' 'year'}} years

Since {{dateDiff '2023-12-01T14:30:00+05:30' 'NOW' 'days'}} days

{{#if (gt (dateDiff '2023-12-01T14:30:00+05:30' 'NOW' 'days') 10)}}More than 10 days!{{else}} Less than 10 days!{{/if}}

Output:
1555200000 ms
1555200 secs
25920 mins
432 hours
18 days
2 weeks
0 months
0 years

Since 18 days

More than 10 days!
To format date value{{formatDate timestamp_with_timezone 'short'}}
{{formatDate timestamp_with_timezone 'short' 'en-in'}}
{{formatDate timestamp_with_timezone 'short' 'en-in' '+05:30'}}
{{formatDate timestamp_with_timezone 'medium'}}
{{formatDate timestamp_with_timezone 'medium' 'en-in'}}
{{formatDate timestamp_with_timezone 'medium' 'en-in' '+05:30'}}
{{formatDate timestamp_with_timezone 'long'}}
{{formatDate timestamp_with_timezone 'long' 'en-in'}}
{{formatDate timestamp_with_timezone 'long' 'en-in' '+05:30'}}
{{formatDate '2023-10-25T18:30:00Z' 'short'}}
{{formatDate '2023-10-25T18:30:00Z' 'short' 'en-in'}}
{{formatDate '2023-10-25T18:30:00Z' 'short' 'en-in' '+05:30'}}
{{formatDate '2023-10-25T18:30:00Z' 'medium'}}
{{formatDate '2023-10-25T18:30:00Z' 'medium' 'en-in'}}
{{formatDate '2023-10-25T18:30:00Z' 'medium' 'en-in' '+05:30'}}
{{formatDate '2023-10-25T18:30:00Z' 'long'}}
{{formatDate '2023-10-25T18:30:00Z' 'long' 'en-in'}}
{{formatDate '2023-10-25T18:30:00Z' 'long' 'en-in' '+05:30'}}

Output:
10/25/2023
25/10/2023
26/10/2023
Oct 25, 2023
25 Oct 2023
26 Oct 2023
October 25, 2023
25 October 2023
26 October 2023
To format datetime value{{formatDateTime timestamp_with_timezone 'short'}}
{{formatDateTime timestamp_with_timezone 'short' 'en-in'}}
{{formatDateTime timestamp_with_timezone 'short' 'en-in' '+05:30'}}
{{formatDateTime timestamp_with_timezone 'medium'}}
{{formatDateTime timestamp_with_timezone 'medium' 'en-in'}}
{{formatDateTime timestamp_with_timezone 'medium' 'en-in' '+05:30'}}
{{formatDateTime timestamp_with_timezone 'long'}}
{{formatDateTime timestamp_with_timezone 'long' 'en-in'}}
{{formatDateTime timestamp_with_timezone 'long' 'en-in' '+05:30'}}
{{formatDateTime timestamp_with_timezone 'custom' 'en-in' '+05:30'}}
{{formatDateTime '2023-10-25T18:30:00Z' 'short'}}
{{formatDateTime '2023-10-25T18:30:00Z' 'short' 'en-in'}}
{{formatDateTime '2023-10-25T18:30:00Z' 'short' 'en-in' '+05:30'}}
{{formatDateTime '2023-10-25T18:30:00Z' 'medium'}}
{{formatDateTime '2023-10-25T18:30:00Z' 'medium' 'en-in'}}
{{formatDateTime '2023-10-25T18:30:00Z' 'medium' 'en-in' '+05:30'}}
{{formatDateTime '2023-10-25T18:30:00Z' 'long'}}
{{formatDateTime '2023-10-25T18:30:00Z' 'long' 'en-in'}}
{{formatDateTime '2023-10-25T18:30:00Z' 'long' 'en-in' '+05:30'}}
{{formatDateTime '2023-10-25T18:30:00Z' 'custom' 'en-in' '+05:30'}}

Output:
25/10/2023, 18:30
25/10/2023, 06:30 pm
26/10/2023, 12:00 am
25 Oct 2023, 18:30
25 Oct 2023, 06:30 pm
26 Oct 2023, 12:00 am
25 October 2023 at 18:30
25 October 2023 at 06:30 pm
26 October 2023 at 12:00 am
26 October 2023 at 12:00:00 am
To format numeric value{{formatNumber number}}
{{formatNumber number 'en-in'}}
{{formatNumber (math number 'round') 'en-in'}}
{{formatNumber 4000000.112}}
{{formatNumber 4000000.112 'en-in'}}
{{formatNumber (math 4000000.11 'round') 'en-in'}}
{{formatNumber 4000000.112 'en-in' 'notation=compact'}}
{{formatNumber 4000000.112 'en-US' 'notation=compact'}}
{{formatNumber 42456235.112 'en-US' 'notation=compact, minimumFractionDigits=2, maximumFractionDigits=2, style=currency, currency=USD'}}
{{formatNumber 42456235.112 'en-in' 'notation=compact, minimumFractionDigits=2, maximumFractionDigits=2, style=currency, currency=INR'}}

Output:
4,000,000.112
40,00,000.112
40,00,000
40L
4M
$42.46M
₹4.25Cr
To trim spaces from value{{trim variable_name}}{{trim ' Test Name '}}

Output:
Test Name
To trim values to a particular length{{trim variable_name max_length}}{{trim 'First Middle Last Name' 20}}

Output:
First Middle Last Na
To trim value to a particular length and then truncate until the last occurrence of the specified delimiter{{trim variable_name max_length delimiter}}{{trim 'First Middle Last Name' 20 ' '}}

Output:
First Middle Last
To remove a string{{remove variable_name 'remove_char/string'}}{{remove 'Fyno™' '™'}}
{{remove 'Fyno®' '®'}}
{{remove 'Fyno®™' '®|™'}}

Output
Fyno
Fyno
Fyno
To sum multiple numbers{{sumAll start_key 'number_key'}}{{sumAll @root 'investments.amount'}}
{{formatNumber (sumAll @root 'investments.amount') 'en-US' 'style=currency, currency=USD'}}

Output
30
$30.00