Skip to content

Use templates

You can use Jinja2 templates in your documentation mixing it with Markdown in the same .md file!

Warning

this is a very brief introduction to Jinja2. in order to get the full power, we recommend to go through this tutorial and look into Jinja2 documentation.

Typical cases for using templates are:

  • generate dynamic content
  • avoid repetative Markdown code
  • render different Markdown code depending on condition

Templates code is wrapped with one of the following notations

  • {% ... %} - for Statements
  • {{ ... }} - for Expressions to print to the template output
  • {# ... #} - for Comments not included in the template output

Template code on its own is not displayed in the ready Markdown document, only results of the templates application are displayed.

Variables

Set variable is as simple as {% set my_variable = "Variable inside the emplate" %}. In order to outpu the variable add this piece to your Markdown {{my_variable}}.

Variables

First let's declare a text variable . And then print it in bold: String printed by the template.

we can also create variables of other types, for example:

  • lists
  • dictionaries

Now we print my_list = [1, 2, 3, 4, 5] and dict = {'one': 1, 'two': 2, 'three': 3}

We can get separate elements of the dicts and lists. For example first element of the list is 1, and element "two" from the dict is 2

First let's declare a text variable {% set my_variable = "String printed by the template" %}. 
And then print it in bold and red:  **{{my_variable}}**{style="color: red"} .  

we can also create variables of other types, for example:

- lists {% set my_list = [1, 2, 3, 4, 5] %}
- dictionaries {% set my_dict = {"one": 1, "two": 2, "three": 3} %}

Now we print my_list = {{my_list}} and dict = {{my_dict}}

We can get separate elements of the dicts and lists. For example first element of the list is **{{ my_list[0] }}**, 
and element "two" from the dict is **{{ my_dict["two"] }}**

Assign variables in the beginning of the Markdown document

It is more convenient to have all variable declarations in the beginning of your Markdown document rather than having them all scattered thoughout the doc.

Because we declared variables, we can use them in the following text now

I saw an ad for a PHP developer for the Adult Website the other day. It was really attractive but I don't know if I could bring myself to admit before my friends and family that I will be coding in PHP

{% set lang = "PHP" %}
{% set where = "the Adult Website" %}
{% set who =  "family" %}

It is more convenient to have all variable declarations in the beginning of your Markdown document rather than 
having them all scattered thoughout the doc.   

Because we declared variables, we can use them in the following text now

>```
I saw an ad for a {{lang}} developer for {{where}} the other day.     
It was really attractive but I don't know if I could bring myself to admit before my friends and  {{who}}
that I will be coding in {{lang}}
```

Statements

You can use notation {{ ... }} not only to print variables, but also to evaluate some statements (with or without the variables). For example, this {{ 1 + 2 + 3 }} is rendered as 6. And if we declare list like this {% set my_list = [1, 2, 3, 4, 5] %} then {{ my_list[1] + 2 }} will produce 4

In a statement you can use use any of the methods of defined on a python's variable’s type. For example {{ "nincompoop".upper() }} will produce NINCOMPOOP .

Python types methods in Jinja2

check here how to use the following Jinja filters:

1 2 3 4 5
abs() float() lower() round() tojson()
forceescape() map() safe() trim() batch()
select() truncate() capitalize() groupby() min()
unique() center() indent() pprint() slice()
default() int() random() sort() urlencode()
dictsort() join() reject() string() urlize()
last() rejectattr() striptags() wordcount() escape()
replace() sum() wordwrap() first() list()
title() xmlattr() reverse() length() filesizeformat()
dictsort() upper() selectattr() max() attr()

Filters

It is more common to use Jinja2 filters, rather than apply method as we did it in section above.

Jinja2 filter is something we use to transform data held in variables. We apply filters by placing pipe symbol | after the variable followed by name of the filter. MAny of the Python type methods listed in the section above, can be as well applied as filters in Jinja2 templates.

The example, but using filter will be {{ "nincompoop" | upper }} producing same output - NINCOMPOOP

Examples of filters

Filter Description Markdown Output
round round numeric variable {{ 25.6 | round }} 26.0
sort sort list {{ [4, 1, 6, 2] | sort }} [1, 2, 4, 6]
reverse reverse string {{ "NOT A PALINDROME" | reverse }} EMORDNILAP A TON
join join all strings in a list into one string {{ ['a', 2, 'b', '3'] | join('-') }} a-2-b-3
replace replace char in a string {{ "aaaBBBaaa" | replace('B', 'X') }} aaaXXXaaa

Filters can be applied to different types, for example filter replace works not only with a string, but also with a list of strings, being applied to each of its elements {{ ['aB', 'BB', 'c'] | replace('B', 'X') }} produces ['aX', 'XX', 'c']

Loops

The syntaxis of the loop looks like this

{% for item in seq %}
    {{item}}
{% endfor %}

Loops are very handy to avoid Markdown code duplication and generate templates dynamically from data. The following example creates table from the dictionary

Funny American town names (Table generated by the template)

Town State
Boring Oregon
Hell Michigan
Hot Coffee Mississippi
Intercourse Pensylvania
No Name Colorado
Pee Pee Ohaio
{% 
    set towns = [
        {"town": "Boring", "state": "Oregon"},
        {"town": "Hell", "state": "Michigan"},
        {"town": "Hot Coffee", "state": "Mississippi"},
        {"town": "Intercourse", "state": "Pensylvania"},
        {"town": "No Name", "state": "Colorado"},
        {"town": "Pee Pee", "state": "Ohaio"}
    ] 
%}

Funny American town names (***Table generated by the template***)

**Town** | **State**
:--- | ---  
{% for item in towns %} {{ item["town"] }} | {{ item["state"] }} 
{% endfor %}

Diagrams also can be generated using templates

Pie chart from template

pie title Why we use Google "Adult content" : 35 "Lazy typing .com" : 11 "Spell checking" : 51 "Find useful info" : 3
{% 
    set google_stat = [
        {"reason": "Adult content", "percent": 35},
        {"reason": "Lazy typing .com", "percent": 11},
        {"reason": "Spell checking", "percent": 51},
        {"reason": "Find useful info", "percent": 3}
    ] 
%}

```mermaid
pie
    title Why we use Google
    {% for item in google_stat %}"{{ item.reason }}" : {{ item.percent }}
    {% endfor %}
```

Conditions

If-else statement has the following syntaxis

{% if ... %}
    ...
{% elif ... %}
    ...
{% else %}
    ...
{% endif %}

Schrodinger Kenny

Every build of static documentation website will result in a different fate for Kenny

Kenny is dead
{% set schrodinger_kenny = [1,2,3,4,5,6,7,8,9] | random %}

Every build of static documentation website will result in a different fate for Kenny

{% if schrodinger_kenny <= 3 %}
    Kenny is sick.
{% elif 3 < schrodinger_kenny <= 7 %}
    Kenny is dead
{% else %}
    Kenny looks okay --- so far
{% endif %}