Jinja for Flask

Semantics

{% ... %} # statement / tag (do something)
{{ ... }} # expression      (output something)

Filters

You can use filters to pipe variables into functions.

Hello, {{ name|capitalize }}

Jinja2 Docs | Filters

safe

safe filter escapes any html variable so special characters get converted

charconverted
<&lt;
>&gt;
&l&amp;
"&#34;
'&#39;

The point is it to set the text to convert all syntax that a browser could think it html into plain text. This is avoid a XSS.

Imagine we have this Jina tempalte

<h1>Hello {{ leader_board_firstplace }}</h1>

Without converting with safe

# If the first place username is:
<script>steal_cookies()</script>
# will render
<h1>Hello <script>steal_cookies()</script><h1>
# The user's browser will none the wiser and try to run this script code

With safe

# If we instead pipe it into safe which converts the chars:
<h1>Hello {{ leader_board_firstplace|safe }}</h1>
# We will get a cleaned version, that render the same but the browser treats as plain text not html
<h1>Hello &lt;script&gt;steal_cookies()&lt;/script&gt;</h1>

Control Structures

if statements

{% if user %}
    Hello, {{ user }}!
{% else %}
    Hello, Stranger!
{% endif %}

for loops

<ul>
    {% for comment in comments %}
        <li>{{ comment }}</li>
    {% endfor %}
</ul>

Macros

Basically python functions but for rendering templates

macro.html
<!-- defining a function "render_comment" with one input-->
{% macro render_comment(comment) %}
    <li class="macroed_comment">{{ comment }}</li>
{% endmacro %}
index.html
{% import 'macros.html' as macros %}
<ul>
    {% for comment in comments %}
        <!-- calling the function passing in our comment -->
        {{ macros.render_comment(comment) }}
    {% endfor %}
</ul>

Output

output.html
<ul>
    <li class="macroed_comment">first!</li>
    <li class="macroed_comment">nice post</li>
    <li class="macroed_comment">last post</li>
</ul>

Include

You can pull in template code using include

{% include 'common.html' %}

Inhertiance

base.html
<html>
<head>
    <title>{% block title %}My App{% endblock %}</title>
    {% block styles %}
    <link rel="stylesheet" href="site.css">
    {% endblock %}
</head>
<body>
    {% block content %}{% endblock %}
</body>
</html>
index.html
{% extends "base.html" %}

<!-- I want to use the title and add prefix it with 'Home -' -->
<!-- Home - super() = Home - My App -->
<!-- calling super(), pulls the contents of the parent -->
{% block title %}Home - {{ super() }}{% endblock %}

{% block styles %}
    {{ super() }}  <!-- I want to use the parent styles and add my own -->
    <link rel="stylesheet" href="home.css">
{% endblock %}

{% block content %}
    <!--  fully override contents -->
    <h1>Hello, World!</h1>
{% endblock %}

Output

So it

<html>
<head>
    <title>Home - My App</title>
    <link rel="stylesheet" href="site.css">
    <link rel="stylesheet" href="home.css">
</head>
<body>
    <h1>Hello, World!</h1>
</body>
</html>