Bei den von Flask verwendeten Jinja-Templates, handelt es sich um html-Dateien welche mit Template-Syntax erweitert wurden. Diese Syntax erlaubt das Definieren von Blöcken, sowie das Ersetzen von Platzhaltern für einzelne Element oder ganze Listen von Elementen.
# Umgehen mit Listen und Dictionaries
Die Templates erhalten von der Flask-render-Methode benannte Argumente. Dabei kann es sich um einzelne Werte, Listen, Dictionaries oder Listen von Dictionaries handeln.
from flask import render_template
@app.route("/test-template")
def test_template():
details = {"year": 2001, "seasons": 6, "description": "Ein Flugzeug stürzt auf einer einsamen Insel ab..."}
actors = [{"id": 123, "name": "Evangeline Lilly", "rolle": "Kate Austen"}, {"id": 32, "name": "Jorge Garcia", "rolle": "Hugo Reyes"}]
return render_template('test_template.html', title="Lost", details=details, actors=actors)
2
3
4
5
6
7
8
Die Template-Datei test_template.html
gehört in den Unterordner templates
. Neben «normalem» HTML-Code beinhaltet sie spezielle Template-Anweisungen:
{{ title }}
wird ersetzt mit dem Inhalt des übergebenen Argumentstitle
{{ details.seasons }}
wird ersetzt mit dem Eintragseasons
des Dictionarydetails
Hinweis
Alles zwischen {{
und }}
ist ein Ausdruck der ins gerenderte Dokument ausgegeben wird.
Für die Liste actors
brauchen wir eine for-Schleife. Diese wird mit {% for actor in actors %}
eingeleitet und mit {% endfor %}
beendet. Alles was dazwischen steht wird für jeden Listen-Eintrag actor
der Liste ausgegeben. Da es sich bei den einzelnen Listen-Elemente wiederum um Dictionaries handelt, müssen wir auf die einzelnen Dictionary-Einträge zugreifen. Dies geschieht z.B. mit {{ actor.name }}
.
Hinweis
{%
und %}
kennzeichnet einen Kontroll-Struktur-Ausdruck wie ein for
oder ein if
. Kontroll-Strukturen besitzen ein Start- und ein Endtag.
<html>
<head>
<title>`{{ title }}`</title>
<link rel="stylesheet" type="text/css" href="static/style.css">
</head>
<body>
<h1>{{ title }}</h1>
<p>{{ details.description }}</p>
<ul>
{% for actor in actors %}
<li>
<a href="actor?id={{ actor.id }}"><strong>{{ actor.name }}</strong> als {{ actor.rolle }}</a>
</li>
{% endfor %}
</ul>
<p>Anzahl Seasons: {{ details.seasons }}<br>Startjahr: {{ details.year }}</p>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Ruft man die oben definierte Route auf, so kombiniert Flask die bei render_template()
ab dem zweiten Argument übergebenen Python-Variablen mit der im ersten Argument übergebenen Template-Datei. Wir erhalten den folgenden reinen HTML-Output welcher als Antwort an den Client geschickt wird:
<html>
<head>
<title>Lost</title>
<link rel="stylesheet" type="text/css" href="static/style.css">
</head>
<body>
<h1>Lost</h1>
<p>Ein Flugzeug stürzt auf einer einsamen Insel ab...</p>
<ul>
<li>
<a href="actor?id=123"><strong>Evangeline Lilly</strong> als Kate Austen</a>
</li>
<li>
<a href="actor?id=32"><strong>Jorge Garcia</strong> als Hugo Reyes</a>
</li>
</ul>
<p>Anzahl Seasons: 6<br>Startjahr: 2001</p>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Definieren von Blöcken
Oft hat man mehrere Seiten für eine Webapp. Diese sollten alle ähnlich aussehen und besitzen deshalb auch über weite Strecken denselben HTML-Code. Mit den Jinja-Templates kann man ein «Basis»-Template definieren, vorauf dann andere Templates aufbauen können. So erspart man sich viel mehrfachen HTML-Code und kann Änderungen rasch und einheitlich umsetzen.
Wir definieren also ein Template base.html
:
<html>
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="static/style.css">
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
2
3
4
5
6
7
8
9
Unser «Basis»-Template enthält zwei Blöcke: title
und content
. Wenn wir nun in unserem Template test_template.html
dieses «Basis»-Template als Grundlage verwenden, so müssen wir nur noch diese Blöcke definieren. Der Rest wird aus dem «Basis»-Template übernommen.
{% extends 'base.html' %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<h1>{{ title }}</h1>
<p>{{ details.description }}</p>
<ul>
{% for actor in actors %}
<li>
<a href="actor?id={{ actor.id }}"><strong>{{ actor.name }}</strong> als {{ actor.rolle }}</a>
</li>
{% endfor %}
</ul>
<p>Anzahl Seasons: {{ details.seasons }}<br>Startjahr: {{ details.year }}</p>
{% endblock %}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Zuerst wird mit {% extends 'base.html' %}
angegeben, welches «Basis»-Template wir verwenden wollen. Anschliessend werden nur noch die zu überschreibenden Blöcke mit der Syntax {% bock name %}
angeben.
Das Ergebnis der Renderfunktion ist genau gleich wie im Beispiel ohne «Basis»-Template.
- Offizielles Tutorial
- https://flask.palletsprojects.com/en/1.1.x/tutorial/templates/ (opens new window)