TurboGears - Langage de modèle Genshi

Genshi est un langage de modèle basé sur XML. C'est similaire àKid, qui était autrefois le moteur de modèle pour les versions antérieures de TurboGears. Genshi ainsi que Kid sont inspirés par d'autres langages de modèles bien connus commeHSLT, TAL et PHP.

Un modèle Genshi consiste en des directives de traitement. Ces directives sont des éléments et des attributs dans un modèle. Les directives Genshi sont définies dans un espace de nomshttp://genshi.edgewall.org/. Par conséquent, cet espace de noms doit être déclaré dans l'élément racine du modèle.

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
...
</html>

La déclaration ci-dessus signifie que l'espace de noms par défaut est défini sur XHTML et que les directives Genshi ont le préfixe «py».

Directives Genshi

Un certain nombre de directives sont définies dans Genshi. La liste suivante énumère les directives Genshi -

  • py:if
  • py:choose
  • py:for
  • py:def
  • py:match
  • py:with
  • py:replace
  • py:content
  • py:attrs
  • py:strip

Sections conditionnelles

Genshi fournit deux directives pour le rendu conditionnel de content− py: if et py: choose.

py: si

Le contenu de l'élément de cette directive ne sera rendu que si l'expression dans if clauseévalue à vrai. En supposant que les données dans le contexte du modèle sont{‘foo’:True, ‘bar’:’Hello’}, la directive suivante -

<div>
   <b py:if = "foo">${bar}</b>
</div>

aura pour résultat

Hello

Cette sortie, cependant, ne serait pas rendue si ‘foo’ is set to False.

Cette directive peut également être utilisée comme élément. Dans ce cas<py:if> doit être fermé par correspondant </py:if>

<div>
   <py:if test = "foo">
      <b>${bar}</b>
   </py:if>
</div>

py: choisissez

Le traitement conditionnel avancé est possible avec l'utilisation de py:choose en combinaison avec py:when et py:otherwisedirectives. Cette fonctionnalité est similaire àswitch – case construire dans C/C++.

Expression dans py:choose la directive est vérifiée avec différentes valeurs identifiées par py:whenles alternatives et le contenu correspondant seront rendus. Une alternative par défaut peut être fournie sous la forme depy:otherwise directif.

<div py:choose = "foo”>
   <span py:when = "0">0</span>
   <span py:when = "1">1</span>
   <span py:otherwise = "">2</span>
</div>

L'exemple suivant illustre l'utilisation de py:choose et py:whendirectives. Le formulaire HTML publie des données dans / marque l'URL. lemarks() la fonction redirige les marques et les résultats sous la forme d'un objet dictionnaire vers total.htmlmodèle. L'affichage conditionnel deresult Pass/Fail est réalisé en utilisant py:choose et py:when directives.

Script HTML de saisie des marques (marks.html) est la suivante -

<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>

Le code complet de root.pyest comme suit. lemarks() le contrôleur envoie des marques et des résultats à total.html modèle -

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

le total.html dans le dossier templates reçoit les données du dictionnaire et les analyse dans la sortie html conditionnellement comme suit -

<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>

Démarrez le serveur (s'il n'est pas déjà en cours d'exécution)

Gearbox server –reload –debug

Entrer http://localhost::8080/marksform dans le navigateur -

le total.html rendra la sortie suivante -

py: pour

L'élément de la directive py: for est répété pour chaque élément d'un itérable, généralement un objet Liste Python. Siitems = [1,2,3] est présent dans un contexte de modèle, il peut être itéré en suivant py: for directive -

<ul>
   <li py:for = "item in items">${item}</li>
</ul>

La sortie suivante sera rendue -

1
2
3

L'exemple suivant montre les données de formulaire HTML rendues dans le modèle total.html à l'aide de la directive py: for peut également être utilisée comme suit -

<py:for each = "item in items">
   <li>${item}</li>
</py:for>

Script de formulaire HTML

<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>

le loop() Le contrôleur lit les données du formulaire et les envoie à total.template sous la forme d'un objet de liste.

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})

Le modèle temp.html utilise py: for loop pour rendre le contenu de l'objet dict sous la forme d'une table.

<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>

Démarrez le serveur (s'il n'est pas déjà en cours d'exécution)

gearbox server –reload –debug

Entrer http://localhost::8080/marksform dans le navigateur.

La sortie suivante sera affichée dans le navigateur lorsque le formulaire ci-dessus est soumis.

py: def

Cette directive est utilisée pour créer une macro. Une macro est un extrait de code réutilisable du modèle. Tout comme une fonction Python, elle a un nom et peut éventuellement avoir des paramètres. La sortie de cette macro peut être insérée à n'importe quel endroit dans un modèle.

La directive py: def suit la syntaxe suivante -

<p py:def = "greeting(name)">
   Hello, ${name}!
</p>

Cette macro peut être rendue avec une valeur de variable au paramètre «nom».

${greeting('world')}
${greeting('everybody)}

Cette directive peut également être utilisée avec une autre version de la syntaxe comme suit -

<py:def function = "greeting(name)">
   <p>Hello, ${name}! </p>
</py:def>

Dans l'exemple suivant, macro() contrôleur dans root.py envoie un dict objet avec deux clés nom1 et nom2 au modèle 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'}

Ce modèle macro.html contient la définition d'une macro appelée salutation. Il est utilisé pour générer un message d'accueil pour les données reçues du contrôleur.

<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>

Démarrez le serveur à l'aide de la boîte de vitesses

gearbox serve –reload –debug

Appelez le contrôleur de macro () en entrant l'URL suivante dans le navigateur -

http://localhost:8080/macro

La sortie suivante sera rendue dans le navigateur -

py: avec

Cette directive vous permet d'affecter des expressions à des variables locales. Ces variables locales rendent l'expression à l'intérieur moins verbeuse et plus efficace.

En supposant que x = 50 est donné dans les données de contexte pour un modèle, ce qui suit sera le py: with directive -

<div>
   <span py:with = "y = 50; z = x+y">$x $y $z</span>
</div>

Il en résultera la sortie suivante -

50 50 100

Une version alternative pour py: with directive est également disponible -

<div>
   <py:with = "y = 50; z = x+y">$x $y $z</py:with>
</div>

Dans l'exemple suivant, le contrôleur macro () renvoie un objet dict avec les clés name, phy et maths.

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}

Le modèle macro.html ajoute les valeurs des clés phy et maths en utilisant py: with directive.

<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>

Le navigateur affichera la sortie suivante en réponse à l'URL http://localhost:8080/macro

Directives de manipulation de structure

le py:attrs directive ajoute, modifie ou supprime des attributs de l'élément.

<ul>
   <li py:attrs = "foo">Bar</li>
</ul>

Si foo = {‘class’:’collapse’} est présent dans un contexte de modèle, que l'extrait de code ci-dessus rendra.

<ul>
   <li class = "collapse">Bar</li>
</ul>

le py:content directive remplace tout contenu imbriqué par le résultat de l'évaluation de l'expression -

<ul>
   <li py:content = "bar">Hello</li>
</ul>

Étant donné bar = 'Bye' dans les données de contexte, cela produirait

<ul>
   <li>Bye</li>
</ul>

le py:replace directive remplace l'élément lui-même par le résultat de l'évaluation de l'expression -

<div>
   <span py:replace = "bar">Hello</span>
</div>

Étant donné bar = 'Bye' dans les données de contexte, cela produirait

<div>
   Bye
</div>