Templates

Templates are a special kind of alternate 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>

“template” can also be shortened to “t”.

The supported template processors are:

Processor Suffixes Dependencies
default ##template, ##template.default awk must be installed. (This should be installed on all *nix systems)
esh ##template.esh esh must be installed.
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 or ESH Description Source
yadm.arch YADM_ARCH Architecture uname ‑m
yadm.class YADM_CLASS Last defined class yadm config local.class
yadm.classes YADM_CLASSES All classes yadm config ‑‑get‑all local.class
yadm.distro YADM_DISTRO Distribution lsb_release ‑si
or /etc/os-release
yadm.distro_family YADM_DISTRO_FAMILY Distribution Family ID_LIKE from/etc/os‑release
yadm.hostname YADM_HOSTNAME Hostname uname ‑n (without domain)
yadm.os YADM_OS Operating system uname ‑s *
yadm.source YADM_SOURCE Template filename (fully qualified path)
yadm.user YADM_USER Current user id ‑u ‑n
env.VAR   Env variables Any VAR in the environment while yadm templates are processed

* The OS for “Windows Subsystem for Linux” is reported as “WSL”, even though uname identifies as “Linux”.
* If lsb_release is not available, “distro” will be the ID specified in /etc/os-release.

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.
esh
esh is a template processor written in POSIX compliant shell. It allows executing shell commands within templates. This can be used to reference your own configurations within templates.
j2cli
j2cli (or j2) is a Python-based Jinja2 template processor. This fully supports all directives of the Jinja2 library. When your template is processed, the YADM_* values are provided to j2cli as environment variables.
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.

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:
# 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.

If multiple classes are defined, yadm.class=="someclass" will be true if any of the defined classes are “someclass”.

Here is an example.
{% if yadm.os == "Darwin" %}
This block is included for MacOS
{% else %}
This block is included for any other OS
{% endif %}
include
Content can be included from external files using the {% include "filename" %} syntax. The filename may include variables and should be either a path relative to the current template or an absolute path. The included file may itself also use variables, but if-else-endif or include directives are not supported. An example:
{% include "extra/config.{{ yadm.os }}" %}

Updated: