Copy as Markdown[Open in ChatGPT](https://chatgpt.com/?q=Read%20https%3A%2F%2Fcoralogix.com%2Fdocs%2Fuser-guides%2Fnotification-center%2Fdynamic-templating%2Ftera-usage.md%20and%20help%20me%20with%20my%20question%20about%20this%20Coralogix%20documentation%20page.)[Open in Claude](https://claude.ai/new?q=Read%20https%3A%2F%2Fcoralogix.com%2Fdocs%2Fuser-guides%2Fnotification-center%2Fdynamic-templating%2Ftera-usage.md%20and%20help%20me%20with%20my%20question%20about%20this%20Coralogix%20documentation%20page.)

# Tera usage and troubleshooting

Use this guide to build, validate, and troubleshoot Tera templates in Notification Center. The guide covers common issues, error-prevention techniques, and best practices when writing dynamic templates for connectors, presets, and routing rules.

For full syntax, filters, and operators, see the [Tera syntax reference](https://keats.github.io/tera/docs/).

## 1. Handle missing fields to avoid rendering failures[​](#1-handle-missing-fields-to-avoid-rendering-failures "Direct link to 1. Handle missing fields to avoid rendering failures")

If a required field is missing from the data, template rendering fails.

To prevent this, always provide a default value or check if the variable is defined before using it.

### Use a default value[​](#use-a-default-value "Direct link to Use a default value")

```
{{ featureName | default('Unknown Feature') }}
```

### Check if a variable exists[​](#check-if-a-variable-exists "Direct link to Check if a variable exists")

```
{%- if featureName is defined -%}

  {{ featureName }} is released!

{%- elif bugDescription is defined -%}

  Bug reported: {{ bugDescription }}

{%- else -%}

  NA

{%- endif -%}
```

Undefined variables cause render errors. Always guard or default optional fields.

## 2. Prevent JSON parsing failures in presets[​](#2-prevent-json-parsing-failures-in-presets "Direct link to 2. Prevent JSON parsing failures in presets")

### Symptom[​](#symptom "Direct link to Symptom")

* Template fails to render.
* JSON parsing errors appear.
* Happens when inserting unescaped text into JSON fields.

### Cause[​](#cause "Direct link to Cause")

If the rendered value contains unescaped quotes, the JSON field becomes invalid.

### Solution: sanitize fields with `json_encode`[​](#solution-sanitize-fields-with-json_encode "Direct link to solution-sanitize-fields-with-json_encode")

Always encode free-form strings inserted into JSON.

**Correct:**

```
{

  "description": {{ alertDef.description | json_encode }}

}
```

**Incorrect:**

```
{

  "description": "Some description with "Quotes inside" "

}
```

`json_encode` escapes internal quotes and ensures valid JSON.

## 3. Fix `is` conditions used on missing fields[​](#3-fix-is-conditions-used-on-missing-fields "Direct link to 3-fix-is-conditions-used-on-missing-fields")

### Symptom[​](#symptom-1 "Direct link to Symptom")

Conditions like:

```
alertDef.entityLabels["key"] is containing("value")
```

fail with: `Test call failed`.

### Cause[​](#cause-1 "Direct link to Cause")

String tests fail if the field is undefined.

### Solution: guard with `is defined`[​](#solution-guard-with-is-defined "Direct link to solution-guard-with-is-defined")

```
alertDef.entityLabels["key"] is defined

and alertDef.entityLabels["key"] is containing("value")
```

Regex example:

```
alertDef.entityLabels["service"] is defined

and alertDef.entityLabels["service"] is matching("checkout")
```

## 4. Format dates from timestamps[​](#4-format-dates-from-timestamps "Direct link to 4. Format dates from timestamps")

Convert timestamps to readable dates using the `date` filter.

Tera expects timestamps in seconds, so convert milliseconds or other units before formatting. Use `epoch_seconds` to safely handle raw numeric timestamps:

```
{{ maintenanceDate | epoch_seconds | date(format="%d/%m/%y - %H:%M:%S") }}
```

If timezone information is also needed (using `%Z` or `%z`), supply a `timezone` parameter to the `date` function. In nearly all cases, timestamps are UTC, so specify UTC explicitly:

```
{{ maintenanceDate | epoch_seconds | date(format="%d/%m/%y - %H:%M:%S %Z", timezone="UTC") }}
```

Without the timezone parameter, the template will fail to render.

However, if the input value is already a date string (e.g., `2022-02-02`, `2022-02-02T12:34:56`, `2022-02-02T12:34:56+0100`), the timezone parameter is not required: Tera will infer UTC or the correct timezone automatically.

## 5. Define variables to simplify logic[​](#5-define-variables-to-simplify-logic "Direct link to 5. Define variables to simplify logic")

Assign variables using `set` to avoid repetition.

```
{%- set priority = alert.highestPriority | default(value=alert.priority) -%}

{%- if priority == "P1" -%}

  critical

{%- elif priority == "P2" -%}

  error

{%- elif priority == "P3" -%}

  warning

{%- else -%}

  info

{%- endif -%}
```

### Variable scope inside loops[​](#variable-scope-inside-loops "Direct link to Variable scope inside loops")

Use `set_global` when a value must persist outside a loop.

```
{% set default_key = "default_key" %}



{% for s in keys %}

  {% if s[0] == alertDef.someService %}

    {% set_global default_key = "" %}

    {% break %}

  {% endif %}

{% endfor %}



{{ default_key }}
```

## 6. Iterate over key–value pairs[​](#6-iterate-over-keyvalue-pairs "Direct link to 6. Iterate over key–value pairs")

```
{% for key, value in _context.entityLabels %}

  {{ key }}: {{ value }}{% if not loop.last %}, {% endif %}

{% endfor %}
```

Use this pattern to print all labels dynamically.

## 7. Remove extra spaces and newlines[​](#7-remove-extra-spaces-and-newlines "Direct link to 7. Remove extra spaces and newlines")

Tera preserves whitespace. Trim using `{%-` and `-%}`.

```
{%- for item in items -%}

  Example

{%- endfor %}
```

Keeps rendered output compact.

## 8. Explore available variables[​](#8-explore-available-variables "Direct link to 8. Explore available variables")

Print the entire context:

```
{{ get_context() | json_encode(pretty=true) }}
```

This reveals objects such as `alertDef`, `alert`, `case`, and `_context`.

Note

Use schema references for accurate field names:

* [Alerts schema](https://coralogix.com/docs/docs/user-guides/notification-center/entity-types/introduction/.md#work-with-alert-entities)
* [Cases schema](https://coralogix.com/docs/docs/user-guides/notification-center/entity-types/introduction/.md#work-with-case-entities)

## 9. Extract alert log example[​](#9-extract-alert-log-example "Direct link to 9. Extract alert log example")

The `get_log` function extracts alert log examples. Use it only in alert-related templates.

```
{{ get_log() | json_encode(pretty=true) }}
```

## 10. Project JSON object fields[​](#10-project-json-object-fields "Direct link to 10. Project JSON object fields")

To extract a subset of JSON object fields, use the `pick` function. Construct the resulting object by using either `include` or `exclude` projection parameters:

```
{# The resulting object will contain `priority`, `metrics.value` keys #}

{{ get_log() | pick(include = ["priority", "metrics.value"]) | json_encode(pretty = true) }}



{# The resulting object will contain everything except `metrics` key #}

{{ get_log() | pick(exclude = ['metrics']) | json_encode(pretty = true) }} 



{# Error. It doesn't support brackets based indexing, use .<index> instead #}

{{ get_log() | pick(include = ['groups[0].value']) | json_encode(pretty = true) }}

{# The resulting object will contain {groups: [null, {value: ...}]} #}

{{ get_log() | pick(include = ['groups.1.value']) | json_encode(pretty = true) }}
```

## Next steps[​](#next-steps "Direct link to Next steps")

See a complete walkthrough of routing alert notifications to Slack in [Example: route alerts to Slack](https://coralogix.com/docs/docs/user-guides/notification-center/user-scenarios/alerts-to-slack/.md).
