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)
1
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 Arguments title
  • {{ details.seasons }} wird ersetzt mit dem Eintrag seasons des Dictionary details

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

1
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/
Letzte Änderung: 7.5.2020, 07:54:59