In the previous Jinja2 post, we have seen a basic use case for network configuration automation. In this post, let’s dive into the basics of Python Jinja2 templating library. The intent is to cover fundaments of jinja2 that most of the time are overlooked because tend to dive directly into the “how to use jinja2” aspect. This post is going to deal with the syntax and semantics of Jinja2
- {# …… #} text between this is regarded as comment.
- {{ …….. }} variables you want to substitute go in here.
- {% …. %} conditional blocks. If, else, for etc
For example:-
{# this is a comment and will not be included in
the rendered output of jinja2 template
#}
hostname {{ hostname }} {# {{hostname}} is a variable that will be substituted here #}
!
interface Loopback0
ip address {{ loopback }}
!
{# {%..%} below is the conditional block #}
{% for vlan, name in vlans.items() %}
vlan {{ vlan }}
name {{ name }}
!
{% endfor %} {# end of conditional block for loop #}
To the above jinja2 template, if we pass in the below dictionary as an example:-
{
'hostname': 'my-rtr-01',
'loopback': '1.1.1.1 255.255.255.255',
'vlans': {'data': 10, 'voice': 20, 'mgmt': 30},
'interfaces' : ['Fa0/1', 'Fa0/2', 'Gig0/1', 'Gig0/2', 'Gig0/3']
}
you can reference the attributes of this dictionary inside Jinja2 as {{hostname}}, {{loopback}}, {{vlans}} but if you want to reference data VLAN specifically, then you can say {{vlans.data}} or {{vlans[‘data’]}}. Both of these notations work fine, it’s just a matter of preference. The only limitation being you cant use the dot notation to access variables with space in the name
Control Statements / Control Structures / Conditional blocks / Conditional Statements
- FOR – used to iterate over an interable. For example:-
{# iterate over a list of interfaces as in above dictionary and print interface #}
{% for interface in data.interfaces %}
{{ interface }}
{% endfor %}
─ python3 main.py ─╯
Fa0/1
Fa0/2
Gig0/1
Gig0/2
Gig0/3
2. IF – validate a condition before proceeding
{% for interface in data.interfaces %}
{% if 'Fa' in interface %}
FA Interface {{interface }}
{% elif "Gig" in interface %}
GIG Interface {{ interface }}
{% endif %}
{% endfor %}
╰─ python3 main.py ─╯
FA Interface Fa0/1
FA Interface Fa0/2
GIG Interface Gig0/1
GIG Interface Gig0/2
GIG Interface Gig0/3
If you see, Jinja is introducing a lot of blank lines and empty white spaces in the output. There is a way to get around this problem, rather a couple of ways to get around this problem.
- First solution, also the easiest
# add lstrip_blocks = True
# trim_blocks = True
# these strip off spaces and lines from blocks.
env = Environment(loader = FileSystemLoader('./'), lstrip_blocks=True, trim_blocks=True)
- Second solution is the usage of {%- at the begining of the block or ending the block with -%}. If you would like to strip the white space before the block, use ‘-‘ minus sign at the beginning of the block or if you want to strip white spaces after the end of the block, use ‘-‘ at the end of the block.
You could also use shorthand notation for the conditional blocks. Instead of using a separate line for the start and end of the block, each block can be done inline. For example:-
{%- for interface in data.interfaces -%}
{{interface}}
{%- endfor %}
could also be written as
{%- for interface in data.interfaces -%}{{interface}}{%- endfor %}
Inside Jinja2 syntax, you could also use all operators as you would do in python language. Operators like
- Maths operators like +,-,*,/ etc
- Logic operators like for, if, and, or, not, in, is, not in etc
- Comparison operators like =, !=,,>, <, >= etc etc
{{ 3 – 2 }}
{{ 3 + 2 }}
Let’s take another example:-
{% set variable1 = 30 %}
{% if variable1 > 50 %}
Hello
{% else %}
Jinja2
{% endif %}
Explanation:-
- set variable1 = 30
- check if variable1 > 50
- If yes, print Hello
- otherwise print Jinja2
Read more here
https://jinja.palletsprojects.com/en/3.0.x/templates/
Next up is an advanced topic of understanding Jinja2 Template Inheritance. This is the most useful feature of Jinja2 should you wish to use jinja in a project and realize its full potential.