# Templating system

## Template model

<DataSchema id="607306" />

### Types

The type of template implies its content properties.

#### `plain` template

This type of template contains only body and can be sent via any channel.

```json
{
    "type": "plain",
    "content": { 
        "body": "Hei {{name}}"
    }
}
```

#### `email` template

This type of template can be sent via `email` channel.

```json
{
    "type": "email",
    "content": { 
        "subject": "Welcome!", 
        "body": "<b>Hei {{name}}</b>", 
        "preheader": "We welcome you" 
    }
}
```

#### `bee_email` template

This type of template is used internally by MPC UI.

It differs from `email` by containing JSON source which is used by JSON generated by [Beefree](https://docs.beefree.io/beefree-sdk) to generate HTML `body` (readonly).

#### `push` template

This type of template can be sent via `push` channel.

```json
{
  "type": "push",
  "content": { 
    "subject": "Welcome", 
    "body": "Hi {{name}}!", 
    "url": "iml://app/cpn",
    "data": { "something":  "special" },
    "android_payload": { "notification_count":  420 },
    "ios_payload": { "badge": 33 }
  }
}
```

See more:

* https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#androidnotification
* https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification#2943363

#### `generic` template

This type of template can be assigned to any channel, so any possible content attribute can be set.

It's meant to be used as a generic wrapper in appliances where the template needs to be utilized by messages sent via various channels.

```json
{
  "type": "generic",
  "content": { 
      "subject": "Welcome", 
      "body": "Hi {{name}}!", 
      "url": "iml://app/cpn" 
  }
}
```

## Liquid template language

We use [Liquid](https://shopify.github.io/liquid) template language for generating dynamic [Message](doc-354471) content.

### Template content example

<Container>
Having this as a body of SMS sent to MPC members:

```text
{% if member_bonus_points %}
    Your points balance is {{ member_bonus_points }}! :)
{% else %}
    You have no points :(
{% endif %}
```    

A following text will be received by member that has some points:

```text
Your points balance is 540 :)
```

A following text will be received by member that has no points:

```text
You have no points :(
```
</Container>

### Merge properties

:::warning[]
This section is outdated and is going to be reworked soon.
:::

The set of merge-properties available for given Message depends on recipient type the Message is being sent to.

For MPC members (fetched from [audience](doc-354473#audience-recipients) or provided as [recipients](doc-354473#mpc-member-recipient)), their MPC data may be used as merge-tags within all Template content attributes:

merge-tag  | Description 
---------- | ------- 
`member_id` |
`member_secret_id`  | Special member's ID of used to authorize member in some MPC services 
`member_msisdn`  |
`member_email` |
`member_app_token`|
`member_*` | Member property (e.g. `member_first_name`) - the set depends on LC configuration
`dmp_*` | DMP value for member (e.g. `dmp_bonus_points`) - available for audience members only, the set depends on LC configuration

For [arbitrary recipients](doc-354473#arbitrary-recipient), only their identifiers and arbitrary data provided within `properties`  may be used .

<Container>
**Example**

For Sending with arbitrary recipients provided as following:

```json
[
  { "email": "piotr@example.com", "properties": { "first_name": "Piotr", "some_object": { "points": 15} } },
  { "email": "ola@example.com", "properties": { "first_name": "Ola", "some_object": { "points": 42 } } }
]
```

The properties may be used like this:

```text
Hello {{ first_name }}.
Your email is {{ email }}.
Your points balance is {{ some_object.points }}.
```
</Container>

## Internationalized content

It is possible to internationalize content of the Messages.

Firstly, you have to add `language` property to the `content` payload to make it the default content version.
Secondly, versions for another languages should be provided in the `translations` property - it is an array of contents (having the same data format as regular one) in other languages.

During sending execution, a specific language version of content will be chosen for each recipient. For member recipients it will be resolved from its profile, for arbitrary recipients it must be provided as property when scheduling Sending.

<Container>
Example:

```json
{
  "template": {
    "type": "plain",
    "content": { "language": "en", "body": "Hi {{first_name}}. Sent at  {{date}}" },
    "translations": [
      { "language": "pl", "body": "Witaj {{first_name}}. Wysłano {{date}}" },
      { "language": "no", "body": "Hallo {{first_name}}. Postet {{date}}" }
    ]
  }
}
```
</Container>

## Template wrapping

<Columns>
  <Column>
A Template may be wrapped by another [Template (Standalone)](doc-354680) by providing `wrapper_id`.

On sending execution, if channel's template has a wrapper assigned, each content attribute (body, subject, etc) of the template will be injected into special `{{ content }}` merge-property of corresponding wrapper's attribute.

When wrapper has no specific content attribute defined, it will be ignored.

Wrapping is not recursive, so if template A has a template B as a wrapper and template B has a template C as a wrapper,
template A will be wrapped by Template B, but template B will not be wrapped by Template C.

The type of wrapper that can be assigned to a template depends on given template type, as follows:

Template type | Wrappable with
------------- | -------------- 
`plain`       | `generic`, `email`, `bee_email`, `push`, `plain`
`generic`     | `generic`, `email`, `bee_email`, `push`
`email`       | `generic`, `email`, `bee_email`
`push`        | `generic`, `push`
`bee_email`   | `generic`
  </Column>
  <Column>
Sample wrapper definition:

```json
{
  "id": 609193,
  "wrapper_id": null,
  "type": "generic",
  "content": { 
    "subject": "Important message for {{member_first_name}}", 
    "body": "Hi {{member_last_name}}! {{content}}",
    "url": null // Empty, so it won't be used on wrapping
  }
}
```

Consider this wrapper to be assigned to a template as following:

```json
{
  "id": 609194,
  "wrapper_id": 609193,
  "type": "push",
  "content": { 
    "subject": "I will be replaced by wrapper", 
    "body": "Your last name is {{member_last_name}}!",
    "url": "foo://bar"
  }
}
```

Effectively, following content will be used during sending execution after wrapping and merging:

```json
{ 
  "subject": "Important message for Piotr", 
  "body": "Hi Piotr! Your last name is Świtlicki!",
  "url": "foo://bar"
}
```
  </Column>
</Columns>
