Jinja2 Tutorial - A Crash Course for Beginners

, February 1st 2021

Jinja2 is one of the most elegant templating languages out there. It is seriously awesome. I loved it from the moment I first came across it. The user experience centres around readability and simplicity. In this crash course, I'll show you what I mean with a ton of examples.

Let us start with the most basic question.

What is Jinja2?

Jinja is a templating engine for developers that uses the Python programming language. It's often referred to as "Jinja2", in reference to its release version.

Jinja2 in Network Automation

The original library was created by Armin Ronacher in 2008. Back then, the library was used almost exclusively by web developers.

Over the years, however, this didn't remain the case.

With the advent of protocols such as NETCONF, the demand for network automation soared. This created a new challenge in the industry. How could network operators manage network configuration in highly dynamic environments?

In the end, the industry gravitated towards Jinja2 as the de facto templating language for network configuration.

That's why, when you browse the web, you'll frequently encounter Jinja2 in network automation tutorials. Additionally, enterprise-grade applications such as Ultra Config Generator and Ansible Tower offer full support for the Jinja2 language.

Let's learn Jinja2

For our crash course today, let's learn through examples.

We'll start basic, and then ramp up to some more complex syntax. By the end of this course, I hope you'll gain an appreciation for the elegant nature of Jinja2.

One other thing. This post will focus on the syntax of the Jinja2 language. If you're looking for an engine to render templates yourself, check out Ultra Config Generator or the Jinja2 package for Python.

Example One: Variable Substitution

The most simple Jinja2 template is just a body of text with a variable. Take a look at the template below.

Hello {{ NAME }}

Variables in Jinja2 are enclosed with two curly braces on each side. Here we have a single variable called NAME. Let's suppose we render the template with the variable set to "John". In this case, the template will render as follows.

Hello John

Example Two: Arithmetic

In the first example, we set our variable to a string.

Jinja2 supports other data types too. Let's use integers to perform a calculation.

Adding {{ X }} and {{ Y }} equals {{ X + Y }}

In this example, the template takes two integers as inputs, X and Y. When rendered, the input values will be displayed as well as their sum.

Let's render the template with X equal to 7, and Y equal to 11.

Adding 7 and 11 equals 18

So we're able to add integers using a plus sign inside curly braces.

Example Three: Complex Arithmetic

The second example was trivial, but Jinja2 is capable of complex arithmetic; the expressions inside the curly braces simply need to conform to Python syntax.

Let's illustrate this with a template that calculates the area of a circle.

A circle with a radius of {{ RADIUS }} has an area of {{ 3.1415*RADIUS**2 }}

An asterisk is used for multiplication. The double asterisk is used to square the value of the radius. This is standard Python syntax.

Let's supply a radius of 5 to demonstrate the calculation.

A circle with a radius of 5 has an area of 78.5375

Example Four: Comments

All languages need a way for developers to annotate their work with comments.

Jinja2 is no exception. Comments can be added with a curly brace and hash on each side.

{# This is an example of a comment #}
Hello {{ NAME }}

When we render the template, comments will be omitted.

Hello John

Example Five: Filters

Variables can be mutated using filters. To use a filter, just add a pipe symbol followed by the name of the filter.

In the template below, a greeting is displayed twice. First, with an uppercase filter, and second with a lowercase filter.

{{ GREETING | upper }}
{{ GREETING | lower }}

Suppose we render the template with the GREETING variable set to "Hello". We'll then get the result below.

HELLO
hello

For the full range of available filters, check out this link.

Example Six: If Statements

It is frequently necessary to use conditional logic in a markup language. To do so with Jinja2, we use the "if" statement.

In the example below, a greeting will be generated based on the value of the GENDER variable.

{% if GENDER == 'Male' %}
Hello Sir
{% elif GENDER == 'Female' %}
Hello Madam
{% else %}
Hello
{% endif %}

The "if" and "elif" statements are followed by boolean expressions that use a Python-like syntax. And all statements are wrapped in curly braces and percentage signs.

Let's render the template with the GENDER variable set to "Female".

Hello Madam

Example Seven: Boolean Operators

Jinja2 supports the use of boolean operators within expressions. These are the keywords "and", "or", and "not".

Here is an example of a template that displays a greeting based on the outcome of multiple conditions.

{% if GENDER == 'Male' and AGE >= 18 %}
Hello Sir
{% elif GENDER == 'Female' and AGE >= 18 %}
Hello Madam
{% else %}
Hello
{% endif %}

Let's render the template with the GENDER variable set to "Male" and the AGE variable set to 16.

Hello

Example Eight: For Loops

Template developers frequently need to loop over lists of items. We can do this in Jinja2 using a "for-loop".

Let's demonstrate a loop with a template that generates a greeting for every name provided.

{% for name in NAMES %}
Hello {{ name }}
{% endfor %}

To render this template correctly, we need to set the NAMES variable to an array of names.

For example, we can set the variable to ["Melinda", "Thomas", "Zac"]. This will render the template with three greetings.

Hello Melinda
Hello Thomas
Hello Zac

Example Nine: Dictionaries

Dictionaries are a useful data type built into most languages including Jinja2.

A dictionary is a set of key-value pairs. Here's an example of a dictionary holding the details of an employee.

{
  "name": "Melinda",
  "age": 25,
  "gender": "Female"
}

We can use dictionaries in Jinja2 templates by referencing properties with a dot.

Here's an example of a template that references three dictionary properties.

+------------------------+
|    Employee Details    |
+---------+-----+--------+
| Name    | Age | Gender |
+---------+-----+--------+
| {{ EMPLOYEE.name }} | {{ EMPLOYEE.age }}  | {{ EMPLOYEE.gender }} |
+---------+-----+--------+

Let's render the template by setting the EMPLOYEE variable to a dictionary.

+------------------------+
|    Employee Details    |
+---------+-----+--------+
| Name    | Age | Gender |
+---------+-----+--------+
| Melinda | 25  | Female |
+---------+-----+--------+

Example Ten: Looping over a list of dictionaries

Let's combine our for-loop and dictionary examples to show off the power of Jinja2.

We'll start by defining a list of employees. Each employee object is a dictionary containing three properties.

[
  {
    "name": "Melinda",
    "age": 25,
    "gender": "Female"
  },
  {
    "name": "Natalie",
    "age": 42,
    "gender": "Female"
  },
  {
    "name": "Madison",
    "age": 30,
    "gender": "Female"
  }
]

And here is a template for generating a table for all employees. It works by looping over the EMPLOYEES list and printing a row for each employee.

+------------------------+
|    Employee Details    |
+---------+-----+--------+
| Name    | Age | Gender |
+---------+-----+--------+
{% for EMPLOYEE in EMPLOYEES %}
| {{ EMPLOYEE.name }} | {{ EMPLOYEE.age }}  | {{ EMPLOYEE.gender }} |
{% endfor %}
+---------+-----+--------+

Let's render the template using our sample data.

+------------------------+
|    Employee Details    |
+---------+-----+--------+
| Name    | Age | Gender |
+---------+-----+--------+
| Melinda | 25  | Female |
| Natalie | 42  | Female |
| Madison | 30  | Female |
+---------+-----+--------+

Where to from here?

There we go, that's everything essential you need to know to get started with Jinja2!

If you'd like to delve deeper into the full capabilities of the language, take a look at the official Jinja2 documentation.

And if you're looking for a platform to help you build and manage Jinja2 templates, check out Ultra Config Generator. The application includes a REST API to fully enable automated solutions based on Jinja2 templates.

That will be it for today's post. Thanks for reading, and take care until next time!

Ultra Config


JOIN THE DISCUSSION

Subscribe to the Blog

Subscribe now and never miss a new post!