my cheat sheet python jinja2 templates

Home

1 jinja2 overview

Twinkle, twinkle, litte {{stellar object}},
How I {{action}} what you are.
Up above the {{place}} so high,
Like a {{allegory}} in the sky

Jinja2 is originally built for python.

Jinja2 is a templating standard, where a document (template) can have variable substitution, {{ my_variable }}, and some amount of logic, {%%} for loops.

Jinja2 (often used with flask) is a python module that allows you to easily incorporate templates to allow your ansible routine to modify many different files, with unique fields

So, every color tag will look like:   \[\033[COLORm\]
where COLOR is:
Black:  30
Red:    31
Green:  32
Yellow: 33
Blue:   34
Purple: 35
Cyan:   36
White:  37

Jinja2 can also be used direclty in an ansible playbook , i.e.

vars:
  my_file: "fixupfile"
debug: 
  msg: "My fixup file is {{ my_file }}"

2 Workflow (using python)

2.1 Working with .csv file for parameters

import csv

sourcefile = "vm_colours.csv"

with open(sourcefile) as f:
   reader = csv.DictReader(f)
   # DictReader lets us read the header values from the csv as well
   # as the usual data fields.
   # reader is an object type "OrderedDict"  type(reader) ===> "OrderedDict"
   for row in reader:
       print(row)  # while building code, good to scatter prints throughout

# run this in ipython to get a feel for what is in the .csv file
# then you can create a jinja2 template to read the data you need from it.

2.2 Sample jinja2 writing unique .bashprofile files

#!/usr/bin/env python
''' generate .bash_profile files unique to the guest vm

For ansible playbook. xxx.yml that will use the jinja2 ansible module.
In parallel, save each unique .bash_profile file as vm1.txt, vm2.txt, etc.

'''

import csv
from jinja2 import Template

colours_csv = "vm_colours.csv"
bash_template = "templates/bash_profile.j2"


with open(bash_template) as f:
    bash_profile_template = Template(f.read(), keep_trailing_newline=True)


with open(colours_csv) as f:
    reader = csv.DictReader(f)
    for row in reader:
        newprofile = bash_profile_template.render(
            c1 = row["User_colour"],
            c2 = row["Host_colour"],
            c3 = row["Dollar_colour"]
        )
        vm_profile = row["Guest_VM"] + ".txt"
        print(f' writing bash profile to local file: {vm_profile}')

        with open(vm_profile, "w") as g:
            g.write(newprofile)

print("\n\nDone.    Check out the new .txt files created in this directory\n")

3 Jinja2 filters

Examples should suffice:

"Province of employment : {{ work_prov | upper }}"  changes province to all uppercase
"Postal code : {{ addr_postalcode | lower }}"       changes to lower case.
"President was: {{ "Donald Trump" | replace ("Trump", "Drumpf") }}"  replaces a keyword
{{ [1, 2, 3] | min }}  returns 1
{{ [1, 2, 3] | max }}  returns 3
{{ [10] | random }}    returns a random number from 1 to 10

3.1 Loading jinja2 templates from a file using FileSystemLoader

from jinja2 import Environment, FileSystemLoader
file_loader = FileSystemLoader('templates')   # templates is a directory
env = Environment(loader=file_loader)
template = env.get_template('python_actors.j2')

output = template.render()
print(output)

Now, in the templates directory we can create a file called python_actors.j2

Hello Monty Python, including
John Cleese
Michael Palin
Terry Jones
Eric Idle
Terry Gilliam
Graham Chapman 

3.2 Using simple template variables from the above example

from jinja2 import Environment, FileSystemLoader
file_loader = FileSystemLoader('templates')   # templates is a directory
env = Environment(loader=file_loader)
template = env.get_template('python_actors.j2')

output = template.render(actorgroup='Cast of Holy Grail')
print(output)

Now, in the templates directory we can create a file called python_actors.j2

Hello {{actorgroup}}, including
John Cleese
Michael Palin
Terry Jones
Eric Idle
Terry Gilliam
Graham Chapman 

3.3 Using more complex template variables from the above example

from jinja2 import Environment, FileSystemLoader
file_loader = FileSystemLoader('templates')   # templates is a directory
env = Environment(loader=file_loader)
template = env.get_template('python_actors.j2')

troup = {}   # a dictionary
troup['name'] = 'Monty Python'
troup['act1'] = 'John Cleese'
troup['act2'] = 'Michael Palin'
troup['act3'] = 'Terry Gilliam'
troup['act4'] = 'Terry Jones'
troup['act5'] = 'Eric Idle'
troup['act6'] = 'Graham Chapman'

output = template.render(actorgroup=troup)
print(output)

Now, in the templates directory we can create a file called python_actors.j2

Hello {{actorgroup.name}}, including
{{actorgroup.act1}}}
{{actorgroup.act2}}}
{{actorgroup.act3}}}
{{actorgroup.act4}}}
{{actorgroup.act5}}}
{{actorgroup.act6}}}

3.4 Control structures and for loops in complex templates

3.4.1 If statements

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

Then the python code could be:

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

Will result in

This is true

3.4.2 for loops.

{% for colour in colours %}
  {{ colour }}
{% endfor %}

Then the corresponding python code to use this template is:

template = env.get_template('doc_colours.j2')
colours = ['red', 'yellow', 'green', 'blue', 'purple', 'orange' ]

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

3.5 Home