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>