# Templating guide

> Reference guide for OneFuse Jinja2 templating, including expressions, filters, tests, control structures, and Property Toolkit features

---

Site [llms.txt](/llms.txt)

---

A template contains [variables](#variables) and/or [Expressions](/docs/onefuse/templating/expressions/), which get replaced with values when a template is rendered; and [tags](#tags-delimiters-summary), which control the logic of the template.

## Tags delimiters summary

`{% ... %}` for [Control structures](/docs/onefuse/templating/control-structures/).

`{{ ... }}` for [variables](#variables) and/or expressions to print to the template output.

`{# ... #}` for [comments](#comments) not included in the template output.

## Variables

Template variables are defined by the context properties passed to the template.

You can use a dot (`.`) to access attributes of a variable in addition to the syntax (`[]`).

The following two lines result in the same outcome:

```jinja2
{{ foo.bar }}
{{ foo["bar"] }}
```

The outer double-curly braces are not part of the variable, but the print statement. The outer double curly-braces are not necessary when you access variables inside tags.

If a variable or attribute does not exist, an undefined value will get returned and will evaluate to an empty string if printed by default.

## Filters

Modify variables with [Filters](/docs/onefuse/templating/filters/).

Filters are separated from the variable by a pipe symbol (`|`) and may have optional arguments in parentheses.

Multiple filters can be chained and the output of one filter is applied to the next.

**Example:**

```jinja2
{#
The example below uses the filter "first" to get the first letter of the variable.
Then, a second filter is applied "lower" to lowercase variable.
#}

{% set OS = "Linux" %}
{{ OS | first | lower }}

=> l
```

## Tests

Tests are used to test a [variable](#variables) against a common expression. To test a variable or expression, add the `is` operator with the test after the variable.

**Example:**

```jinja2
{% if OS is defined %}
  {% if Environment == "prod" %}
    {# Naming Policy Name for prod #}
    production
  {% elif Environment == "dev" %}
    {# Naming Policy Name for dev #}
    development
  {% elif Environment == "qa" %}
    {# Naming Policy Name for qa #}
    qa
  {% else %}
    {# Naming Policy Name default #}
    global
  {% endif %}
{% endif %}
```

Will return `true` or `false` depending on whether the `OS` variable is defined in the current properties input.

## Comments

Use the comment syntax `{# ... #}` tag to comment-out a part of a line in a template.

**Example:**

```jinja2
{# My Comment #}
```

## Escaping

The Template Engine will start to handle delimiter starters unless you escape the characters or blocks, which may be necessary to ignore.

The easiest way to output a literal variable delimiter (`{{`) is by using a variable expression:

```jinja2
{{ '{{' }}

{# For bigger blocks of text, we recommend you to use raw tags #}
{% raw %}
my
block
of
text
{% endraw %}
```

## If

Refer to [Control structures: if](/docs/onefuse/templating/control-structures/#if).

## Macros

Macros are comparable with functions in regular programming languages. They are useful to put often used idioms into reusable functions to not repeat yourself.

Below is a small example of a macro that renders the first lowercased letter from the variable:

```jinja2
{% macro firstLowercase(value='') -%}
  {{ value | first | lower }}
{%- endmacro %}
```

<div class="alert alert-info" role="alert">


If a macro name starts with an underscore (`_`), it is not exported and it cannot be imported.
</div>


The macro can then be called like a function in the namespace:

```jinja2
{% set OS = "Linux" %}
{% set Environment = "production" %}
{% set Application = "Web Servers" %}

{{ firstLowercase(OS) }}{{ firstLowercase(Environment) }}{{ firstLowercase(Application) }}

{# The above is equivalent to
  {{ OS | first | lower }}{{ Environment | first | lower }}{{ Application | first | lower }}
#}

=> lpw
```

Inside macros, you have access to three special variables:

| Variable | Description |
| --- | --- |
| `varargs` | If more positional arguments are passed to the macro than accepted by the macro, they end up in the special `varargs` variable as a list of values. |
| `kwargs` | Like `varargs` but for keyword arguments. All unconsumed keyword arguments are stored in this special variable. |
| `caller` | If the macro was called from a [call](#call) tag, the caller is stored in this variable as a callable macro. |

Macros also expose some of their internal details. The following attributes are available on a macro object:

| Attribute | Description |
| --- | --- |
| `name` | The name of the macro. `{{ input.name }}` will print input. |
| `arguments` | A tuple of the names of arguments the macro accepts. |
| `defaults` | A tuple of default values. |
| `catch_kwargs` | This is `true` if the macro accepts extra keyword arguments (i.e.: accesses the special `kwargs` variable). |
| `catch_varargs` | This is `true` if the macro accepts extra positional arguments (i.e.: accesses the special `varargs` variable). |
| `caller` | This is `true` if the macro accesses the special `caller` variable and may be called from a [call](#call) tag. |

## Call

In some cases it can be useful to pass a macro to another macro. For this purpose, you can use the special `call` block.

The following example shows a macro that takes advantage of the call functionality and how it can be used:

```jinja2
{% macro render_dialog(title, class='dialog') -%}
  <div class="{{ class }}">
    <h2>{{ title }}</h2>
    <div class="contents">
      {{ caller() }}
    </div>
  </div>
{%- endmacro %}

{% call render_dialog('Hello World') %}
  This is a simple dialog rendered by using a macro and a call block.
{% endcall %}
```

It is also possible to pass arguments back to the call block. This makes it useful as a replacement for loops. Generally speaking, a call block works exactly like a macro without a name.

Here's an example of how a call block can be used with arguments:

```jinja2
{% macro get_users(users) -%}
  <ul>
    {%- for user in users %}
      <li><p>{{ user.username|e }}</p>{{ caller(user) }}</li>
    {%- endfor %}
  </ul>
{%- endmacro %}

{% call(user) get_users(list_of_user) %}
  <dl>
    <dl>First Name</dl>
    <dd>{{ user.first_name | e }}</dd>
    <dl>Last Name</dl>
    <dd>{{ user.last_name | e }}</dd>
  </dl>
{% endcall %}
```

---

Section pages:

- [Best practices](/docs/onefuse/templating/best-practices/): Best practices for OneFuse templating
- [Property Sets](/docs/onefuse/templating/property-sets/): OneFuse Property Sets overview
- [Quick reference](/docs/onefuse/templating/quick-reference/): Quick reference examples for common OneFuse templating patterns
- [Expressions](/docs/onefuse/templating/expressions/): Reference for OneFuse Jinja2 expressions including literals, math, comparisons, logic, and operators
- [Control structures](/docs/onefuse/templating/control-structures/): Reference for OneFuse Jinja2 control structures including for loops, if statements, and variable assignment
- [Tests](/docs/onefuse/templating/tests/): Reference for OneFuse Jinja2 tests used to evaluate variables and expressions
- [Filters](/docs/onefuse/templating/filters/): Reference for OneFuse Jinja2 filters used to transform and format variable values
