> ## Documentation Index
> Fetch the complete documentation index at: https://v0.x-docs.novu.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Handlebars & Helpers

# Handlebars

The Novu notification content editor relies on Handlebars.js to establish the logic and control flow of our workflows.
For a deeper comprehension of Handlebars.js, you can refer to its [documentation](https://handlebarsjs.com/guide/#what-is-handlebars).

This resource offers comprehensive insights into the utilization of Handlebars.js in crafting dynamic and adaptable notification content within the Novu platform.

| Helper          | Description                                                                     | Example                                                          | Output                                                |
| --------------- | ------------------------------------------------------------------------------- | ---------------------------------------------------------------- | ----------------------------------------------------- |
| if              | Conditionally renders a block. Falsy values won't be rendered.                  | `{{#if author}}<h1>{{firstName}} {{lastName}}</h1>{{/if}}`       | Renders `<h1>Yehuda Katz</h1>` if `author` is truthy. |
| includeZero     | `includeZero=true` treats the conditional as not empty, handling 0 differently. | `{{#if 0 includeZero=true}}<h1>Does render</h1>{{/if}}`          | Renders `<h1>Does render</h1>` for 0.                 |
| Sub-Expressions | Create custom logic helpers and use them in sub-expressions.                    | `{{#if (isdefined value1)}}true{{else}}false{{/if}}`             | Renders `true` or `false` based on custom helper.     |
| unless          | Inverse of if helper. Renders a block if the expression is falsy.               | `{{#unless license}}<h3 class="warning">WARNING</h3>{{/unless}}` | Renders warning if `license` is falsy.                |
| each            | Iterate over a list. Use this to reference the iterated element.                | `{{#each people}}<li>{{this}}</li>{{/each}}`                     | Renders list items.                                   |
| with            | Change context for template parts.                                              | `{{#with person}}{{firstname}} {{lastname}}{{/with}}`            | Renders `firstname` and `lastname` from the context.  |
| Nested each     | Access iteration variables in nested each blocks.                               | `{{#each array}}{{@index}}: {{this}}{{/each}}`                   | Renders index and item in each iteration.             |
| Nested with     | Use with block parameters for clear code.                                       | See above example with nested with and complex template.         | Renders nested context values.                        |
|                 | You can use else section to handle empty values.                                | `{{#with city}}...{{else}}No city found{{/with}}`                | Handles empty context case.                           |

# Novu-specific helpers

| Handlebar Expression                       | Description                                                                                                                                                                                                                           |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{{dateFormat date 'EEEE, MMMM Do yyyy'}}` | You can format the date using the `dateFormat` function. Here, `date: '2020-01-01'` has been formatted into `Wednesday, January 1st 2020`.                                                                                            |
| `{{lowercase key}}`                        | This helps you use the `lowercase` handlebar helper function and turns the value of the specified key to its lowercase value. So, for `message: 'hEllo WORLD'`, if we write `{{lowercase message}}`, we'll end up with `hello world`. |
| `{{uppercase key}}`                        | This helps you use the `uppercase` handlebar helper function and turns the value of the specified key to its uppercase value. So, for `message: 'hello woRld'`, if we write `{{uppercase message}}`, we'll end up with `HELLO WORLD`. |
| `{{titlecase key}}`                        | This helps you use the `titlecase` handlebar helper function and turns the value of the specified key to its titlecase value. So, for `message: 'hEllo wOrLD'`, if we write `{{titlecase message}}`, we'll end up with `Hello World`. |

### groupBy

`groupBy` helper is used to group the items in an array based on a property.

<Tabs>
  <Tab title="Template">
    ```html theme={null}
    {{#each (groupBy names "name")}}
      <h1>{{key}}<h1>
      {{#each items}}
        <h3>{{age}}</h3>
      {{/each}}
    {{/each}}
    ```
  </Tab>

  <Tab title="Context">
    ```json theme={null}
    {
      "names": [
        {
          "name": "Name 1",
          "age": "30"
        },
        {
          "name": "Name 2",
          "age": "31"
        },
        {
          "name": "Name 1",
          "age": "32"
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Output">
    ```html theme={null}
    <h1>Name 1<h1>
    <h3>30</h3>
    <h3>32</h3>
    <h1>Name 2<h1>
    <h3>31</h3>
    ```
  </Tab>
</Tabs>

### equals

`equals` helper allows you to perform comparisons, both for boolean expressions and string comparisons.

<Tabs>
  <Tab title="Template">
    ```html theme={null}
    <!-- LOGIC -->
    {{#equals value1 value2}}
       <!-- Code to execute when value1 is equal to value2 -->
    {{else}}
       <!-- Code to execute when value1 is not equal to value2 -->
    {{/equals}}


    <!-- Example -->
    {{#equals 10 1}}
       <h2> 10 is equal to 1 </h2>
    {{else}}
       <h1> 10 is not equal to 1 </h1>
    {{/equals}}
    ```
  </Tab>

  <Tab title="Context">
    ```json theme={null}
    {
      "value1" : 10,
      "values2" : 1
    }
    ```
  </Tab>

  <Tab title="Output">
    ```html theme={null}
       <h1> 10 is not equal to 1 </h1>
    ```
  </Tab>
</Tabs>

### numberFormat

`numberFormat` helper is used to format numbers with specified decimal length, thousands separator, and decimal separator.

<Tabs>
  <Tab title="Template">
    ```html theme={null}
    <div>{{numberFormat number decimalSep="," decimalLength="2" thousandsSep="|"}}</div>
    <div>{{numberFormat nonNumber decimalSep="," decimalLength="2" thousandsSep="|"}}</div>
    ```
  </Tab>

  <Tab title="Context">
    ```json theme={null}
    {
      "number": 1000000000,
      "nonNumber": "Not a number"
    }
    ```
  </Tab>

  <Tab title="Output">
    ```html theme={null}
    <div>1|000|000|000,00</div>
    <div>Not a number</div>
    ```
  </Tab>
</Tabs>

### pluralize

The `pluralize` helper allows you to easily handle pluralization in your templates by providing different forms of a word depending on a variable value.

### Basic Usage

In its simplest form, the `pluralize` helper takes three arguments:

```
{{pluralize count singular plural}}
```

* `count`: The numeric value that determines whether the singular or plural form should be used.
* `singular`: The singular form of the word.
* `plural`: The plural form of the word.

#### Example

```
{{pluralize dog_count "dog" "dogs"}}
```

In this example, if `dog_count` is equal to 1, it will render "1 dog," and if it's greater than 1, it will render "dogs."

## Use Cases & Examples

### Handling Event Count Display with Excluded Individuals

In some cases, you may want to display the total count of certain events but exclude specific individuals who are already mentioned. For example, when using a phrase like "John and `{{step.total_count}}` people liked your photo," you may notice that the count is off by one because "John" is already mentioned.

To account for such scenarios, you can utilize the following approach:

```
{{#each step.events}}
  {{#if @first}}
    {{this.name}}
  {{else}}
    {{#if @last}}
      and {{@index}}
    {{/if}}
  {{/if}}
{{/each}}
followed you!
```

In this code, we iterate through the `step.events` array and conditionally display each name. If it's the first name in the list, it will be shown without "and." For subsequent names, we add "and" before the last name. This ensures that the count is not affected by names that are explicitly mentioned in the message.

By using this code, you can achieve a more accurate representation of the event count in your messages, even when some users are individually mentioned in the message text.

### Using array length as count

Array length be used as total number of item. For example, if paylod have fruits property of type array then its length can be used as total number of fruits.

<Tabs>
  <Tab title="Template">
    ```html theme={null}
    Total number of fruits is {{fruits.length}}.
    ```
  </Tab>

  <Tab title="Payload">
    ```json theme={null}
    {
      "fruits": [
        {
          "name": "Pine apple",
          "price": "10$"
        },
        {
          "name": "Apple",
          "age": "8$"
        },
        {
          "name": "Orange",
          "age": "5$"
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Output">
    ```html theme={null}
    Total number of fruits is 3.
    ```
  </Tab>
</Tabs>

<Note> In a future release, we plan to replace handlebar helpers with an alternative solution. Please note that custom handlebars in the editor itself are not currently supported. If we are missing any handlebar helper that is blocking you to write template for use case, feel free to reach out to us in [discord](https://discord.gg/novu?ref=docs-handlebar-helper)</Note>
