---
title: "Templates"
permalink: /docs/templates
---
Templates are a special kind of [alternate](/docs/alternates) file. The template
content and host specific data are combined as input to a template processor
which produces a new file as its output.

This can be very useful if you need to vary a small part of a file, but it
doesn't support any kind of include directive.

## Template suffixes

To create a template, append an alternate suffix to the file name.
The suffix has the format:

    ##template.<template processor>

<sub><sup>
"template" can also be shortened to "t".
</sup></sub>

The supported template processors are:

| Processor | Suffixes                             | Dependencies                                                            |
| -         | -                                    | -                                                                       |
| default   | `##template`, `##template.default`   | `awk` must be installed. (This should be installed on all *nix systems) |
| j2cli     | `##template.j2`, `##template.j2cli`  | `j2cli` must be installed.                                              |
| envtpl    | `##template.j2`, `##template.envtpl` | `envtpl` must be installed.                                             |

The processor can be omitted for "default".
Also, `j2` will be processed by either j2cli or envtpl, whichever is found.

## Exposed data

When template processors run, they will be provided the following set of data.


| Default (built-in) | Jinja           | Description                | Source                                         |
| -                  | -               | -                          | -                                              |
| `yadm.class`       | `YADM_CLASS`    | Locally defined yadm class | <code>yadm&nbsp;config&nbsp;local.class</code> |
| `yadm.distro`      | `YADM_DISTRO`   | Distribution               | <code>lsb_release&nbsp;&#8209;si</code>        |
| `yadm.hostname`    | `YADM_HOSTNAME` | Hostname                   | `hostname` (without domain)                    |
| `yadm.os`          | `YADM_OS`       | Operating system           | <code>uname&nbsp;&#8209;s</code> <sup>*</sup>  |
| `yadm.user`        | `YADM_USER`     | Current user               | <code>id&nbsp;&#8209;u&nbsp;&#8209;n</code>    |
| `yadm.source`      | `YADM_SOURCE`   | Template filename          | (fully qualified path)                         |

<sub><sup>*
The OS for "Windows Subsystem for Linux" is reported as "WSL", even though uname identifies as "Linux".
</sup></sub>

## Supported template processors

default
: This built-in processor requires no additional software (assuming your distro
contains `awk`). This processor has a syntax _similar_ to the Jinja processors
below, however it only supports a small set of directives. Those directives are
detailed in the section below.

j2cli
: [j2cli][j2cli] (or `j2`) is a Python-based Jinja2 template processor. This
fully supports all directives of the [Jinja2 library][jinja]. When your template is
processed, the YADM_* values are provided to j2cli as environment variables.

envtpl
: [envtpl][envtpl] is another Python-based Jinja2 template processor. Online
comments suggest this software might not be maintained anymore.

## Built-in directives
yadm's "default" (built-in) template processor supports the following directives.

{% raw %}
variables
: Variables should be surrounded by `{{ }}`. It is fine for there to be
whitespace between the variable name and the double braces. The `{{` and
`}}` must be on the same line. For example:

```jinja
# WARNING: Do not edit this file.
# It was generated by processing {{ yadm.source }}
```

if-else-endif
: Entire blocks of content can be included or excluded based on the value of a
variable. Only equality can be tested. These blocks must start with
`{% if yadm.variable == "value" %}` and end with `{% endif %}`. An alternative
block can also be specified using the directive `{% else %}`. These directives
must appear on lines by themselves. They may not appear on the same line. The
"if" directive only supports testing a single variable, and there is no "elif"
directive as there is in Jinja. Here is an example.

```jinja
{% if yadm.os == "Darwin" %}
This block is included for MacOS
{% else %}
This block is included for for any other OS
{% endif %}
```

{% endraw %}

[envtpl]: https://github.com/andreasjansson/envtpl
[j2cli]: https://github.com/kolypto/j2cli
[jinja]: https://jinja.palletsprojects.com
