Jinja for Flask
Semantics
{% ... %} # statement / tag (do something)
{{ ... }} # expression (output something)Filters
You can use filters to pipe variables into functions.
Hello, {{ name|capitalize }}safe
safe filter escapes any html variable so special characters get converted
| char | converted |
|---|---|
| < | < |
| > | > |
| & | l& |
| " | " |
| ' | ' |
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 codeWith 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 <script>steal_cookies()</script></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>