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
{%
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 %}