Skip to content

Templates

Projekt «WebApp»

Bei den von Bottle verwendeten 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. Die Templates werden im Unterordner views abgespeichert.

Umgehen mit Listen und «Named Tuples»

Wenn wir von der Datenbank Datensätze erhalten, so geschieht dies in Form von Listen bestehend aus sogenannten «Named Tuples». Diese Werte wollen wir nun im HTML-Code einbauen. Dazu rufen wir die template-Funktion auf. Ihr muss als erstes Argument der Name der html-Templatedatei übergeben werden. Anschliessend folgen beliebig viele keyword-Arguments mit den im Template darzustellenden Daten.

einzelne Variable

Das Template erhält eine einzelne Variable, z.B. den Titel der Webseite:

python
from bottle import request, route, run, static_file, template

@route('/test')
def test():
    return template("test.html", title="Hallo Welt")
html
<html>
    <head>
        <title>{{title}}</title>
    </head>
    <body>
        Die Webseite heisst: {{title}}
    </body>
</html>

Als Platzhalter wird im Template der Name der Variablen in doppelte geschweifte Klammern gesetzt. Dieser Platzhalter wird dann mit dem Wert der Variablen ersetzt.

Liste

Bei einer Liste brauchen wir im Template eine Art for-in-Schleife. Der im Schleifeninhalt entstehende HTML-Code wird dann für jedes Element erzeugt und kann natürlich dieses Element beinhalten.

python
from bottle import request, route, run, static_file, template

@route('/todo')
def todo():
    return template("todo.html", todo=["Abwasch", "Wäsche", "Aufräumen"])
html
<html>
    <head>
        <title>Todo</title>
    </head>
    <body>
    <ul>
      % for item in todo:
        <li>{{item}}</li>
      % end
    </ul>
    </body>
</html>

Im Template wird der Start der for-Schleife mit Hilfe von % for.. gekennzeichnet. Ebenso muss ein Ende mit % end gekennzeichnet sein.

Named Tuple

«Named Tuples» sind fast wie Objekte von Python. Einfach ohne Methoden, nur mit den Eigenschaften. Das praktische: die Eigenschaften können mit Punktnotation angesprochen werden. Diese Punktnotation kann direkt im Template im schon bekannten Platzhalter eingesetzt werden.

python
@route('/movie')
def movie():

    # Datensatz oder Objekt
    Movie = namedtuple("Movie", "name description")
    movie = Movie("Lost", "Ein Flugzeug stürzt auf einer einsamen Insel ab...")
    print(movie)
    
    return template("movie.html", movie=movie)
html
<html>
    <body>
    <h1>{{movie.name}}</h1>
    <p>{{movie.description}}</p>
    </body>
</html>

Liste von Named Tuples

Die Datenbank liefert uns Datensätze als Liste von «Named Tuples». Die Liste können wir mit der for-in-Schleife im Template durchgehen. Da die Elemente der Liste nun «Named Tuples» sind, können wir auf deren Attribute/Eigenschaften mit der Punktnotation zugreifen.

python
from bottle import request, route, run, static_file, template
from collections import namedtuple # nur zu Testzwecken, kommt sonst aus DB

@route('/actors')
def actors():
   
    # Liste von Werten/Datensätzen
    Actor = namedtuple("Actor", "id name rolle")
    actors = [Actor(123, "Evangeline Lilly", "Kate Austen"), Actor(32, "Jorge Garcia", "Hugo Reyes")]
    print(actors)
    
    return template("actors.html", actors=actors)
html
<html>
    <body>
    <ul>
      % for actor in actors:
        <li>{{actor.name}} als {{actor.rolle}}</li>
      % end
    </ul>
    </body>
</html>

Alles kombinert

python
from bottle import request, route, run, static_file, template
from collections import namedtuple # nur zu Testzwecken, kommt sonst aus DB

@route('/kombiniert')
def kombiniert():
    # einzelner Wert
    title = "Hello World"
    
    # Datensatz oder Objekt
    Movie = namedtuple("Movie", "name description")
    movie = Movie("Lost", "Ein Flugzeug stürzt auf einer einsamen Insel ab...")
    
    # Liste von Werten/Datensätzen
    Actor = namedtuple("Actor", "id name rolle")
    actors = [Actor(123, "Evangeline Lilly", "Kate Austen"), Actor(32, "Jorge Garcia", "Hugo Reyes")]
    
    return template("kombiniert.html", title=title, movie=movie, actors=actors)
html
<html>
    <head>
        <title>{{title}}</title>
    </head>
    <body>
    <h1>{{movie.name}}</h1>
    <p>{{movie.description}}</p>
    <ul>
      % for actor in actors:
        <li>{{actor.name}} als {{actor.rolle}}</li>
      % end
    </ul>
    </body>
</html>

weitere Template-Syntax

Neben der Schleife, lässt das Template auch Verzweigungen if-elif-else zu:

html
% if item.type == "movie":
    <p>Film des Jahres</p>
% elif item.type == "serie":
    <p>Serie des Jahres</p>
% else:
    <p>weiss-nicht-was des Jahres</p>
% end

Python-Blöcke

Es sind auch Python-Blöcke möglich im Template:

html
% name = " kate austen  "  # eine Zeile Python-Code
<p>html-inhalt</p>
<%
  # Ein mehrzeiliger Python-Block
  name = name.title().strip()
%>
<p>mehr html-inhalt</p>

Template-Funktionen

Damit nicht jedes Template die ganze Webseite umfassen muss, gibt es zwei Funktionen bei den bottle-Templates:

include

Damit können wir ein anderes Template in unserem Template integrieren. Z.B. Kopf- und Fussbereich der Webapp:

html
% include('header.html', title='Meine Seite')
Seiteninhalt
% include('footer.html')

rebase

Hier können wir das Ergebnis des aktuellen Templates in eine anderes Template integrieren. Dabei wir der HTML-Code des aktuellen Templates als Variable base dem anderen Template übergeben.

html
% rebase('base.html', title='Seitentitel')
<p>Seiteninhalt...</p>
html
<html>
<head>
  <title>{{title or 'Kein Titel'}}</title>
</head>
<body>
  {{!base}}
</body>
</html>

Im Platzhalter steht !base. Durch das Ausrufezeichen wird html-Code in der Variablen base zugelassen und nicht in normale Zeichen umgewandelt. Mit dem or im Titel-Platzhalter kann ein Default-Wert gesetzt werden, falls title nicht gesetzt wird.

Gymnasium Kirchenfeld, fts & lem