Jinja2 Templating Engine Tutorial

Jason Rigden
4 min readJan 22, 2018

--

Check out my podcast, “Talking Cryptocurrency” where I interview with the people making the cryptocurrency and blockchain revolution happen. Guests have ranged from solo devs to CEOs. These are quick 15–20 minutes episodes. Read my Podcast Manifesto or listen to the show now.

In this post we are going to explore:

  • What template engines do
  • Loading templates
  • Template variables
  • Template control structures
  • Template inheritance

What template engines do

Template engines are kind of like a super charged version of Madlibs.

A very short & simple example:

{{name}} had a little {{animal}}.

If name=’mary’ and animal=’lamb’

Would be:

Mary had a little lamb.

Python’s built-in string formatters are great. I covered the sting .format()
in a previous video. But maybe you need something a bit more powerful. If so than Jija2 will probably meet you needs.

“Jinja2 is a modern and designer-friendly templating language for Python, modelled after Django’s templates.”
From the Jinja2 docs

Template engines are most often used in web apps.

An HTML example:

<html>
<head>
<title>{{title}}</title>
</head
<body>
<h1>{{header}}</h1>
<p>{{body}}</p>
</body>
</html>

But they are not exclusively for web templates. They can be used anytime you need to generate text.

Loading Templates

If you are using Jinja2 within a web framework,then you should use their recommended method. As stated earlier, using Jinja2 is not exclusive to web frameworks. It can be used anytime you want to have text generated from a template. In this post we will not be using a web framework. This will reduce the complexity of the example code. There are several ways to load templates. We will be using the FileSystemLoader in this post. All of the code example will have this import statement implied.

from jinja2 import Environment, FileSystemLoader

We pass the directory containing the templates to the FileSystemLoader.

file_loader = FileSystemLoader(‘templates’)

Then we load the environment.

env = Environment(loader=file_loader)

We make our first template inside of the template directory. We call it hello_world.txt Inside hello_world.txt we put.

Hello, World!

Now we can load the template.

template = env.get_template(‘hello_world.txt’)

Then we can render and print.

output = template.render()
print(output)

This will print:

Hello, World!

This is pretty uninteresting. But, it is the most simple example possible. What if we add a variable?

Template Variables

Now we create a new template called, lamb.txt containing:

{{ name }} had a little lamb.

The {{ name }} is a template variable. Now we can load the new template.

template = env.get_template('lamb.txt')

We pass the variable to the template, when we render it.

output = template.render(name='Mary')
print(output)

Output:

Mary had a little lamb

Change the name.

output = template.render(name='Jason')
print(output)

Output:

Jason had a little lamb

We add another variable.

{{ name }} had a little {{ animal }}.

Pass multiple variables.

output = template.render(name=’Bob’, animal=’cat’)
print(output)

Output:

Bod had a little cat.

We can also access more complex objects.

{{ data.name }} had a little {{ data.animal }}.

Pass a dictionary.

person = {}
person[‘name’] = ‘Frank’
person[‘animal’] = ‘dog’

output = template.render(data=person)
print(output)

Output:

Frank had a little dog.

Template Control Structures

Control structures control the flow of the program. We will cover conditionals and for-loops.

Conditionals

We create a template called truth.txt

{% if truth %}
This is true
{% else %}
This is false
{% endif %}

Then render it with the variable.

template = env.get_template(‘truth.txt’)
output = template.render(truth=True)
print(output)

Output:

This is true

Change the value of the variable to False

template = env.get_template('truth.txt')
output = template.render(truth=False)
print(output)

Output:

This is false

For-Loops

We create a template called rainbow.txt

{% for color in colors %}
{{ color }}
{% endfor %}

Render with a list of colors.

template = env.get_template('rainbow.txt')

colors = ['red', 'green', 'blue']

output = template.render(colors=colors)
print(output)

Output:

    red

green

blue

Template Inheritance

Template inheritance allows you to create building blocks that you can combine. In this section we will be using a HTML as an example. We make a template called, header.html

<HEAD>
<TITLE>{{ title }}</TITLE>
</HEAD>

We make a template called, base.html Include the header.html

<HTML>
{% include 'header.html' %}
<BODY>
</BODY>
</HTML>

Now render:

template = env.get_template('base.html')

output = template.render(title='Page Title')
print(output)

Output:

<HTML>
<HEAD>
<TITLE>Page Title</TITLE>
</HEAD>
<BODY>
</BODY>
</HTML>

Now we will enable child templates to use the base.html with blocks.

<HTML>
{% include 'header.html' %}
<BODY>
{% block content %}{% endblock %}
</BODY>
</HTML>

We make a template called, child.html That extends the base.html template.

{% extends "base.html" %}

{% block content %}
<p>
{{ body }}
</p>
{% endblock %}

Now render this new template.

template = env.get_template('child.html')

output = template.render(title='Page Title', body='Stuff')
print(output)

Output:

<HTML>
<HEAD>
<TITLE>Page Title</TITLE>
</HEAD>
<BODY>
<p>
Stuff
</p>
</BODY>

Conclusion

In this post learned:

  • What template engines do
  • Loading templates
  • Template variables
  • Template control structures
  • Template inheritance

Now that you have the basics covered, start coding. Jinja2 has many more features for you to explore.

--

--

Jason Rigden

You may remember me from such projects as The Seattle Podcasters Guild, The Talking Cryptocurrency Podcast, or some of my popular Python tutorials.