Python Jinja Tutorial
Python Jinja Tutorial
Jinja tutorial shows how to create templates in Python with Jinja module.
A template engine or template processor is a library designed to combine templates with a data
model to produce documents. Template engines are often used to generate large amounts of
emails, in source code preprocessing, or producing dynamic HTML pages.
We create a template engine, where we define static parts and dynamic parts. The dynamic parts
are later replaced with data. The rendering function later combines the templates with data.
Jinja installation
$ sudo pip3 install jinja2
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
We use the pip3 tool to install Jinja.
Jinja delimiters
Jinja uses various delimiters in the template strings.
{% %} - statements
{{ }} - expressions to print to the template output
{# #} - comments which are not included in the template output
# ## - line statements
simple.py
#!/usr/bin/env python3
print(msg)
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
The example asks for a user name and generates a message string, which is printed to the user. The
template engine is similar to the Python format() method; but template engines are more powerful
and have many more features.
We import the Template object from the jinja2 module. Template is the central template object. It
represents a compiled template and is used to evaluate it.
In our template, we have the {{ }} syntax which is used to print the variable. The variable is passed
in the render() method.
msg = tm.render(name=name)
With the render() method, we generate the final output. The method joins the template string with
the data passed as argument. The variable that is passed to the render() method is called the context
variable.
$ ./simple.py
Enter your name: Paul
Hello Paul
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
simple2.py
#!/usr/bin/env python3
name = 'Peter'
age = 34
print(msg)
The template string renders two variables: name and age. This time the variables are hard-coded.
$ ./simple2.py
My name is Peter and I am 34
Jinja objects
We can work with objects in our template strings.
objects.py
#!/usr/bin/env python3
class Person:
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
def __init__(self, name, age):
self.name = name
self.age = age
def getAge(self):
return self.age
def getName(self):
return self.name
print(msg)
In the example, we define a Person object. We get the name and age via the two getters.
Dictionaries
Jinja allows a convenient dot notation to access data in Python dictionaries.
dicts.py
#!/usr/bin/env python3
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
# tm = Template("My name is {{ per['name'] }} and I am {{ per['age'] }}")
msg = tm.render(per=person)
print(msg)
We have a person dictionary. We access the dictionary keys with a dot operator.
Both the active and the commented way are valid. The dot notation is more convenient.
raw_data.py
#!/usr/bin/env python3
data = '''
{% raw %}
His name is {{ name }}
{% endraw %}
'''
tm = Template(data)
msg = tm.render(name='Peter')
print(msg)
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
By using the raw, endraw block, we escape the Jinja {{ }} syntax. It is printed in its literal meaning.
escape_data.py
#!/usr/bin/env python3
print(msg)
print(escape(data))
Using the e filter, the data is escaped. Filters are applied with the | character.
print(escape(data))
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Jinja for expressions
The for expression is used to iterate over a data collection in a template.
Now we do not use a simple string template anymore. We use a text file which is loaded with
FileSystemLoader.
for_expr.py
#!/usr/bin/env python3
persons = [
{'name': 'Andrej', 'age': 34},
{'name': 'Mark', 'age': 17},
{'name': 'Thomas', 'age': 44},
{'name': 'Lucy', 'age': 14},
{'name': 'Robert', 'age': 23},
{'name': 'Dragomir', 'age': 54}
]
file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
template = env.get_template('showpersons.txt')
output = template.render(persons=persons)
print(output)
In this example, the template is the showpersons.txt file. The file is located in the templates directory.
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
persons = [
{'name': 'Andrej', 'age': 34},
{'name': 'Mark', 'age': 17},
{'name': 'Thomas', 'age': 44},
{'name': 'Lucy', 'age': 14},
{'name': 'Robert', 'age': 23},
{'name': 'Dragomir', 'age': 54}
]
file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
template = env.get_template('showpersons.txt')
templates/showpersons.txt
{% for person in persons -%}
{{ person.name }} {{ person.age }}
{% endfor %}
In the template file, we use the for expression to iterate over the collection. We show the person's
name and age. The dash character next to the % characters is used to control white space.
Jinja conditionals
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Conditionals are expressions that are evaluated when a certain condition is met.
conditionals.py
#!/usr/bin/env python3
persons = [
{'name': 'Andrej', 'age': 34},
{'name': 'Mark', 'age': 17},
{'name': 'Thomas', 'age': 44},
{'name': 'Lucy', 'age': 14},
{'name': 'Robert', 'age': 23},
{'name': 'Dragomir', 'age': 54},
]
file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
env.trim_blocks = True
env.lstrip_blocks = True
env.rstrip_blocks = True
template = env.get_template('showminors.txt')
output = template.render(persons=persons)
print(output)
The example prints only minor persons; a minor is someone younger than 18.
env.trim_blocks = True
env.lstrip_blocks = True
env.rstrip_blocks = True
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
White space in output can be controlled with environment attributes.
templates/showminors.txt
{% for person in persons %}
{% if person.age < 18 %}
{{- person.name }}
{% endif %}
{%- endfor %}
$ ./conditionals.py
Mark
Lucy
sum_filter.py
#!/usr/bin/env python3
cars = [
{'name': 'Audi', 'price': 23000},
{'name': 'Skoda', 'price': 17300},
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
{'name': 'Volvo', 'price': 44300},
{'name': 'Volkswagen', 'price': 21300}
]
file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
template = env.get_template('sumprices.txt')
output = template.render(cars=cars)
print(output)
In the example, we use the sum filter to calculate the sum of all car prices.
cars = [
{'name': 'Audi', 'price': 23000},
{'name': 'Skoda', 'price': 17300},
{'name': 'Volvo', 'price': 44300},
{'name': 'Volkswagen', 'price': 21300}
]
We have a list of car dictionaries. Each dictionary has a price key. It will be used to calculate the
sum.
templates/sumprices.txt
The sum of car prices is {{ cars | sum(attribute='price') }}
In the template file, we apply the filter on the cars collection object. The sum is calculated from the
price attribute.
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
$ ./sum_filter.py
The sum of car prices is 105900
ineritance.py
#!/usr/bin/env python3
file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
template = env.get_template('about.html')
output = template.render(content=content)
print(output)
base.html
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
{% block content%}
{% endblock %}
</body>
</html>
In the base.html file, we declare two blocks: title and content. These blocks are going to be filled
with specific tags and text in the child templates.
about.html
{% extends 'base.html' %}
{% block content %}
<h1>About page</h1>
<p>
This is about page
</p>
{% endblock %}
The about.html template file inherits from base.html. It adds data specific to this page. We avoid code
repetition; we do not repeat tags that are same for both pages, such as body and html and meta
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
tags.
{% extends 'base.html' %}
We define a title.
{% block content %}
<h1>About page</h1>
<p>
This is about page
</p>
{% endblock %}
app.py
#!/usr/bin/env python3
@app.route("/greet")
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
def greet():
username = request.args.get('name')
return render_template('index.html', name=username)
if __name__ == "__main__":
app.run()
In this Flask application, we get the name of a user and pass it as a parameter to the
render_template() method. The greet() function reacts to the /greet path.
templates/index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Greeting</title>
</head>
<body>
<p>
Hello {{ name }}
</p>
</body>
</html>
This is the template file, located in the templates directory. We add the name of the user to the
template file with {{ name }} syntax.
$ python3 app.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
We start the server.
$ curl http://127.0.0.1:5000/greet?name=Peter
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Greeting</title>
</head>
<body>
<p>
Hello Peter
</p>
</body>
</html>
We connect to the application with the curl tool. We add a name parameter.
Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD