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:
from bottle import request, route, run, static_file, template
@route('/test')
def test():
return template("test.html", title="Hallo Welt")
<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.
from bottle import request, route, run, static_file, template
@route('/todo')
def todo():
return template("todo.html", todo=["Abwasch", "Wäsche", "Aufräumen"])
<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.
@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>
<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.
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>
<body>
<ul>
% for actor in actors:
<li>{{actor.name}} als {{actor.rolle}}</li>
% end
</ul>
</body>
</html>
Alles kombinert
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>
<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:
% 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:
% 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:
% 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.
% rebase('base.html', title='Seitentitel')
<p>Seiteninhalt...</p>
<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.