Jinja2 Templates

Jinja2 Templates

This article shows how to create templates in Python with Jinja module

What is Jinja ?

Jinja is a fast, expressive, extensible templating engine. Special placeholders in the template allow writing code similar to Python syntax. Then the template is passed data to render the final document.

Jinja Installation

We use the pip3 tool to install Jinja.

$sudo pip3 install jinja2

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

Jinja Code Example

First Example

This example asks for a user name and generates a message string, which is printed to the user

#first_jinja_example
from jinja2 import Template
name = input("Enter your name: ")
tmp = Template("Hello {{ name }}")
msg = tmp.render(name=name)
print(msg)

the output:

image.png

  • I imported the Template object from the jinja2 module. Template is the central template object.
  • In our template, we have the {{ }} syntax which is used to print the variable. The variable will be passed in the render method.
  • 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.

Second Example

In this example, we will use two variables:

from jinja2 import Template
name = 'xxxxx'
age = 20
tm = Template("My name is {{ name }} and I am {{ age }}")
msg = tm.render(name=name, age=age)
print(msg)

The output:

image.png

Jinja objects

Example

from jinja2 import Template
class Person:
def **init**(self, name, age):
[self.name](http://self.name/) = name
self.age = age
def getAge(self):
return self.age
def getName(self):
return [self.name](http://self.name/)
person = Person('xxxxx', 23)
tm = Template("My name is {{ per.getName() }} and I am {{ per.getAge() }}")
msg = tm.render(per=person)
print(msg)

The output:

image.png

Jinja Dictionaries

Example

Jinja allows a convenient dot notation to access data in Python dictionaries.

from jinja2 import Template
person = { 'name': 'Person', 'age': 23 }
tm = Template("My name is {{ [per.name](http://per.name/) }} and I am {{ per.age }}")

# tm = Template("My name is {{ per['name'] }} and I am {{ per['age'] }}")
msg = tm.render(per=person)
print(msg)

The output:

image.png

Jinja raw data

Example

We use the raw, endraw block to escape the Jinja {{ }} syntax. It is printed in its literal meaning.

from jinja2 import Template
data = '''
{% raw %}
His name is {{ name }}
{% endraw %}
'''
tm = Template(data)
msg = tm.render(name='Peter')
print(msg)

The output:

image.png

Jinja for expression

The for expression is used to iterate over a data collection in a template. In this example, the template is the showpersons.txt file. The file is located in the templates directory.

{% for p in persons -%}
{{ p.name }} {{ p.age }}
{% endfor %}

The dash character next to the “%” characters is used to control white space.

#for_expression_jinja_example.py

from jinja2 import Environment, FileSystemLoader
persons = [
{'name': 'AAA', 'age': 23},
{'name': 'B', 'age': 24},
{'name': 'CC', 'age': 44},
{'name': 'D', 'age': 14},
{'name': 'EEE', 'age': 23},
{'name': 'F', 'age': 54}
]
file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
template = env.get_template('showpersons.txt')
output = template.render(persons=persons)
print(output)

The output:

AAA 23
B 24
CC 44
D 14
EEE 23
F 54

Jinja conditionals

Conditionals are expressions that are evaluated when a certain condition is satisfied.

Example

The example will print only minor persons(younger than 18) using Jinja conditionals. In this example, the template is the showminors.txt file. The file is located in the templates directory.

{% for p in persons -%}
 {{ p.name }} {{ p.age }}
{% endfor %}
from jinja2 import Template
from jinja2 import Environment,FileSystemLoader
persons = [
{'name': 'AAA', 'age': 23},
{'name': 'B', 'age': 24},
{'name': 'CC', 'age': 44},
{'name': 'D', 'age': 14},
{'name': 'EEE', 'age': 23},
{'name': 'F', '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 outout

D14

Jinja filters

Filters can be applied to data to modify them. For instance, the sum filter can sum data, escape filter escapes them, and sort filter sorts them.

Example

In the template file, we apply the filter on the cars collection object. The sum is calculated from the price attribute. In this example the template is sumpricescars.txt' file.The file is located in the templates directory

The sum of car prices is {{cars | sum(attribute='price')}

sum_filter_jinja_example.py

from jinja2 import Environment, FileSystemLoader
cars = [
 {'name': 'Audi', 'price': 23000},
 {'name': 'Skoda', 'price': 17300},
 {'name': 'Volvo', 'price': 44300},
 {'name': 'Volkswagen', 'price': 21300}
]
file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
template = env.get_template('sumpricescars.txt')
output = template.render(cars=cars)
print(output)

The Output:

image.png

Jinja template inheritance

A strong feature that reduces code duplication and enhances code structure is template inheritance. In other template files, we inherit from the base template that we define. Specific blocks in the basic template file are replaced by these template files.

base.html

<!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>

about.html

{% extends 'base.html' %}
{% block title%}About page{% endblock %}
{% block content %}
<h1>About page</h1>
<p>
 This is about page
</p>
{% endblock %}

inheritance.py

from jinja2 import Environment, FileSystemLoader
content = 'This is about page'
file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
template = env.get_template('about.html')
output = template.render(content=content)
print(output)

The output:

image.png

Jinja Flask example

In this next example, we will create a simple Flask application that uses Jinja.

app.py

from flask import Flask, render_template, request
app = Flask(__name__)
@app.route("/greeting")
def greeting():
 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 greeting function reacts to the /greeting 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>

to run the aplication:

/bin/python3 /home/xxxxx/Desktop/PyNetbox/app.py

We connect to the application with the curl command and we add a name as an argument.

$curl http://127.0.0.1:5000/greet?name=XXXX

The output

image.png