TurboGears - Genshi-Vorlagensprache
Genshi ist eine XML-basierte Vorlagensprache. Es ist ähnlich wieKid, die früher die Template-Engine für frühere Versionen von TurboGears war. Genshi und Kid lassen sich von anderen bekannten Vorlagensprachen wie inspirierenHSLT, TAL und PHP.
Eine Genshi-Vorlage besteht aus Verarbeitungsanweisungen. Diese Anweisungen sind Elemente und Attribute in einer Vorlage. Genshi-Direktiven werden in einem Namespace definierthttp://genshi.edgewall.org/. Daher muss dieser Namespace im Stammelement der Vorlage deklariert werden.
<html xmlns = "http://www.w3.org/1999/xhtml"
xmlns:py = "http://genshi.edgewall.org/"
lang = "en">
...
</html>
Die obige Deklaration bedeutet, dass der Standard-Namespace auf XHTML festgelegt ist und Genshi-Direktiven das Präfix 'py' haben.
Genshi-Richtlinien
In Genshi sind eine Reihe von Richtlinien definiert. Die folgende Liste listet die Genshi-Richtlinien auf -
- py:if
- py:choose
- py:for
- py:def
- py:match
- py:with
- py:replace
- py:content
- py:attrs
- py:strip
Bedingte Abschnitte
Genshi bietet zwei Anweisungen zum bedingten Rendern von Inhalten - py: if und py: Choose.
py: wenn
Der Inhalt des Elements dieser Direktive wird nur gerendert, wenn der Ausdruck in if clausebewertet als wahr. Angenommen, die Daten im Vorlagenkontext sind{‘foo’:True, ‘bar’:’Hello’}, die folgende Richtlinie -
<div>
<b py:if = "foo">${bar}</b>
</div>
wird darin enden, dass
Hello
Diese Ausgabe würde jedoch nicht gerendert, wenn ‘foo’ is set to False.
Diese Direktive kann auch als Element verwendet werden. In diesem Fall<py:if> muss durch entsprechende geschlossen werden </py:if>
<div>
<py:if test = "foo">
<b>${bar}</b>
</py:if>
</div>
py: wähle
Die erweiterte bedingte Verarbeitung ist mit der Verwendung von möglich py:choose in Kombination mit py:when und py:otherwiseRichtlinien. Diese Funktion ähneltswitch – case konstruieren in C/C++.
Ausdruck in py:choose Die Direktive wird mit verschiedenen Werten überprüft, die mit gekennzeichnet sind py:whenAlternativen und entsprechende Inhalte werden gerendert. Eine Standardalternative kann in Form von bereitgestellt werdenpy:otherwise Richtlinie.
<div py:choose = "foo”>
<span py:when = "0">0</span>
<span py:when = "1">1</span>
<span py:otherwise = "">2</span>
</div>
Das folgende Beispiel zeigt die Verwendung von py:choose und py:whenRichtlinien. Das HTML-Formular sendet Daten an / markiert die URL. Dasmarks() Funktion leitet Markierungen um und führt in Form eines Wörterbuchobjekts zu total.htmlVorlage. Die bedingte Anzeige vonresult Pass/Fail wird durch die Verwendung erreicht py:choose und py:when Richtlinien.
HTML-Skript zur Eingabe von Marken (marks.html) ist wie folgt -
<html>
<body>
<form action = "http://localhost:8080/marks" method = "post">
<p>Marks in Physics:</p>
<p><input type = "text" name = "phy" /></p>
<p>Marks in Maths:</p>
<p><input type = "text" name = "maths" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>
Der vollständige Code von root.pyist wie folgt. Dasmarks() Der Controller sendet Markierungen und Ergebnisse an total.html Vorlage -
from hello.lib.base import BaseController
from tg import expose, request
class RootController(BaseController):
@expose("hello.templates.marks")
def marksform(self):
return {}
@expose("hello.templates.total")
def marks(self, **kw):
phy = kw['phy']
maths = kw['maths']
ttl = int(phy)+int(maths)
avg = ttl/2
if avg ≥ 50:
mydata = {'phy':phy, 'maths':maths, 'total':ttl, 'result':2}
else:
mydata = {'phy':phy, 'maths':maths, 'total':ttl,'result':1}
return mydata
Das total.html im Vorlagenordner empfängt Wörterbuchdaten und analysiert sie in der HTML-Ausgabe unter folgenden Bedingungen:
<html xmlns = "http://www.w3.org/1999/xhtml"
xmlns:py = "http://genshi.edgewall.org/"
lang = "en">
<head>
<title>TurboGears Templating Example</title>
</head>
<body>
<h2>Hello, Welcome to TurboGears!.</h2>
<h3>Marks in Physics: ${phy}.</h3>
<h3>Marks in Maths: ${maths}.</h3>
<h3>Total Marks: ${total}</h3>
<div py:choose = "result">
<span py:when = "1"><h2>Result: Fail</h2></span>
<span py:when = "2"><h2>Result: Pass</h2></span>
</div>
</body>
</html>
Starten Sie den Server (falls noch nicht ausgeführt)
Gearbox server –reload –debug
Eingeben http://localhost::8080/marksform im Browser -
Das total.html wird folgende Ausgabe rendern -
py: für
Element in py: for-Direktive wird für jedes Element in einem iterierbaren Objekt, normalerweise einem Python-Listenobjekt, wiederholt. Wennitems = [1,2,3] in einem Vorlagenkontext vorhanden ist, kann es durch folgendes py iteriert werden: for directive -
<ul>
<li py:for = "item in items">${item}</li>
</ul>
Die folgende Ausgabe wird gerendert -
1
2
3
Das folgende Beispiel zeigt HTML-Formulardaten, die in der Vorlage total.html mit py gerendert wurden: for-Direktive kann auch wie folgt verwendet werden:
<py:for each = "item in items">
<li>${item}</li>
</py:for>
HTML-Formularskript
<html>
<body>
<form action = "http://localhost:8080/loop" method="post">
<p>Marks in Physics:</p>
<p><input type = "text" name = "phy" /></p>
<p>Marks in Chemistry:</p>
<p><input type = "text" name = "che" /></p>
<p>Marks in Maths:</p>
<p><input type = "text" name = "maths" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>
Das loop() Der Controller liest Formulardaten und sendet sie in Form eines Listenobjekts an total.template.
from hello.lib.base import BaseController
from tg import expose, request
class RootController(BaseController):
@expose("hello.templates.marks")
def marksform(self):
return {}
@expose("hello.templates.temp")
def loop(self, **kw):
phy = kw['phy']
maths = kw['maths']
che = kw['che']
l1 = []
l1.append(phy)
l1.append(che)
l1.append(maths)
return ({'subjects':['physics', 'Chemistry', 'Mathematics'], 'marks':l1})
Die Vorlage temp.html verwendet die Schleife py: for, um den Inhalt des dict-Objekts in Form einer Tabelle zu rendern.
<html xmlns = "http://www.w3.org/1999/xhtml"
xmlns:py = "http://genshi.edgewall.org/" lang = "en">
<body>
<b>Marks Statement</b>
<table border = '1'>
<thead>
<py:for each = "key in subjects"><th>${key}</th></py:for>
</thead>
<tr>
<py:for each = "key in marks"><td>${key}</td></py:for>
</tr>
</table>
</body>
</html>
Starten Sie den Server (falls noch nicht ausgeführt)
gearbox server –reload –debug
Eingeben http://localhost::8080/marksform im Browser.
Die folgende Ausgabe wird im Browser angezeigt, wenn das obige Formular gesendet wird.
py: def
Diese Anweisung wird zum Erstellen eines Makros verwendet. Ein Makro ist ein wiederverwendbarer Ausschnitt aus Vorlagencode. Ähnlich wie eine Python-Funktion hat sie einen Namen und kann optional Parameter haben. Die Ausgabe dieses Makros kann an einer beliebigen Stelle in eine Vorlage eingefügt werden.
Die py: def-Direktive folgt der folgenden Syntax:
<p py:def = "greeting(name)">
Hello, ${name}!
</p>
Dieses Makro kann mit einem variablen Wert für den Parameter 'name' gerendert werden.
${greeting('world')}
${greeting('everybody)}
Diese Anweisung kann auch mit einer anderen Syntaxversion wie folgt verwendet werden:
<py:def function = "greeting(name)">
<p>Hello, ${name}! </p>
</py:def>
Im folgenden Beispiel: macro() Controller in root.py sendet a dict Objekt mit zwei Schlüsseln name1 und name2 zur Vorlage macro.html.
from hello.lib.base import BaseController
from tg import expose, request
class RootController(BaseController):
@expose('hello.templates.macro')
def macro(self):
return {'name1':'TutorialPoint', 'name2':'TurboGears'}
Diese Vorlage macro.html enthält die Definition eines Makros namens Begrüßung. Es wird verwendet, um eine Begrüßungsnachricht für vom Controller empfangene Daten zu generieren.
<html xmlns = "http://www.w3.org/1999/xhtml"
xmlns:py = "http://genshi.edgewall.org/"
lang = "en">
<body>
<h2>py:def example</h2>
<div>
<div py:def = "greeting(name)">
Hello, Welcome to ${name}!
</div>
<b>
${greeting(name1)}
${greeting(name2)}
</b>
</div>
</body>
</html>
Starten Sie den Server mit dem Getriebe
gearbox serve –reload –debug
Rufen Sie macro () controller auf, indem Sie die folgende URL in den Browser eingeben -
http://localhost:8080/macro
Die folgende Ausgabe wird im Browser gerendert -
py: mit
Mit dieser Anweisung können Sie lokalen Variablen Ausdrücke zuweisen. Diese lokalen Variablen machen den Ausdruck innerhalb weniger ausführlich und effizienter.
Unter der Annahme, dass x = 50 in Kontextdaten für eine Vorlage angegeben ist, lautet das folgende py: mit Direktive -
<div>
<span py:with = "y = 50; z = x+y">$x $y $z</span>
</div>
Dies führt zu folgender Ausgabe:
50 50 100
Eine alternative Version für py: mit Direktive ist ebenfalls verfügbar -
<div>
<py:with = "y = 50; z = x+y">$x $y $z</py:with>
</div>
Im folgenden Beispiel gibt macro () controller ein dict-Objekt mit den Tasten name, phy und maths zurück.
from hello.lib.base import BaseController
from tg import expose, request
class RootController(BaseController):
@expose('hello.templates.macro')
def macro(self):
return {'name':'XYZ', 'phy':60, 'maths':70}
Die Vorlage macro.html fügt Werte von phy- und maths-Schlüsseln mithilfe der Anweisung py: with hinzu.
<html xmlns = "http://www.w3.org/1999/xhtml"
xmlns:py = "http://genshi.edgewall.org/"
lang = "en">
<body>
<h2>py:with example</h2>
<h3>Marks Statement for : ${name}!</h3>
<b>Phy: $phy Maths: $maths
<span py:with = "ttl = phy+maths">Total: $ttl</span>
</b>
</body>
</html>
Der Browser rendert die folgende Ausgabe als Antwort auf die URL http://localhost:8080/macro
Richtlinien zur Strukturmanipulation
Das py:attrs Die Direktive fügt dem Element Attribute hinzu, ändert sie oder entfernt sie.
<ul>
<li py:attrs = "foo">Bar</li>
</ul>
Wenn foo = {‘class’:’collapse’} ist in einem Vorlagenkontext vorhanden, den das obige Snippet rendert.
<ul>
<li class = "collapse">Bar</li>
</ul>
Das py:content Direktive ersetzt verschachtelten Inhalt durch das Ergebnis der Auswertung des Ausdrucks -
<ul>
<li py:content = "bar">Hello</li>
</ul>
Wenn in den Kontextdaten bar = 'Bye' angegeben ist, würde dies erzeugen
<ul>
<li>Bye</li>
</ul>
Das py:replace Direktive ersetzt das Element selbst durch das Ergebnis der Auswertung des Ausdrucks -
<div>
<span py:replace = "bar">Hello</span>
</div>
Wenn in den Kontextdaten bar = 'Bye' angegeben wird, wird dies erzeugt
<div>
Bye
</div>