TurboGears - Lenguaje de plantillas Genshi

Genshi es un lenguaje de plantillas basado en XML. Esto es similar aKid, que solía ser el motor de plantilla para versiones anteriores de TurboGears. Tanto Genshi como Kid se inspiran en otros lenguajes de plantillas bien conocidos comoHSLT, TAL y PHP.

Una plantilla de Genshi consta de directivas de procesamiento. Estas Directivas son elementos y atributos en una plantilla. Las directivas de Genshi se definen en un espacio de nombreshttp://genshi.edgewall.org/. Por lo tanto, este espacio de nombres debe declararse en el elemento raíz de la plantilla.

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

La declaración anterior significa que el espacio de nombres predeterminado está configurado en XHTML y las directivas Genshi tienen el prefijo 'py'.

Directivas de Genshi

En Genshi se definen varias directivas. La siguiente lista enumera las directivas de Genshi:

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

Secciones condicionales

Genshi proporciona dos directivas para la representación condicional de contenido: py: if y py: choose.

py: si

El contenido del elemento de esta directiva se renderizará solo si la expresión en if clausese evalúa como verdadero. Suponiendo que los datos en el contexto de la plantilla son{‘foo’:True, ‘bar’:’Hello’}, la siguiente directiva -

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

resultará en

Hello

Sin embargo, esta salida no se generaría si ‘foo’ is set to False.

Esta directiva también se puede utilizar como elemento. En este caso<py:if> debe ser cerrado por correspondiente </py:if>

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

py: elige

El procesamiento condicional avanzado es posible con el uso de py:choose en combinación con py:when y py:otherwisedirectivas. Esta característica es similar aswitch – case construir en C/C++.

Expresión en py:choose La directiva se verifica con diferentes valores identificados con py:whenSe renderizarán alternativas y contenidos correspondientes. Se puede proporcionar una alternativa predeterminada en forma depy:otherwise directiva.

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

El siguiente ejemplo ilustra el uso de py:choose y py:whendirectivas. El formulario HTML envía datos a / marca la URL. losmarks() La función redirige las marcas y los resultados en forma de un objeto de diccionario a total.htmlmodelo. La visualización condicional deresult Pass/Fail se logra usando py:choose y py:when directivas.

Script HTML para ingresar marcas (marks.html) es el siguiente:

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

El código completo de root.pyes como sigue. losmarks() El controlador envía marcas y resultados a total.html plantilla -

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

los total.html en la carpeta de plantillas recibe datos del diccionario y los analiza en salida html condicionalmente de la siguiente manera:

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

Inicie el servidor (si aún no se está ejecutando)

Gearbox server –reload –debug

Entrar http://localhost::8080/marksform en el navegador -

los total.html renderizará la siguiente salida -

py: para

Elemento en py: la directiva for se repite para cada elemento en un iterable, normalmente un objeto de lista de Python. Siitems = [1,2,3] está presente en un contexto de plantilla, se puede iterar siguiendo py: for directive -

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

Se renderizará la siguiente salida:

1
2
3

El siguiente ejemplo muestra los datos del formulario HTML representados en la plantilla total.html usando py: la directiva for también se puede usar de la siguiente manera:

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

Script de formulario 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>

los loop() el controlador lee los datos del formulario y los envía a total.template en forma de objeto de lista.

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

La plantilla temp.html usa py: for loop para representar el contenido del objeto dict en forma de tabla.

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

Inicie el servidor (si aún no se está ejecutando)

gearbox server –reload –debug

Entrar http://localhost::8080/marksform en el navegador.

El siguiente resultado se mostrará en el navegador cuando se envíe el formulario anterior.

py: def

Esta directiva se utiliza para crear una macro. Una macro es un fragmento reutilizable de código de plantilla. Al igual que una función de Python, tiene un nombre y, opcionalmente, puede tener parámetros. La salida de esta macro se puede insertar en cualquier lugar de una plantilla.

La directiva py: def sigue la siguiente sintaxis:

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

Esta macro se puede representar con un valor variable en el parámetro 'nombre'.

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

Esta directiva también se puede utilizar con otra versión de sintaxis de la siguiente manera:

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

En el siguiente ejemplo, macro() controlador en root.py envía un dict objeto con dos claves name1 y name2 a la plantilla 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'}

Esta plantilla macro.html contiene la definición de una macro llamada saludo. Se utiliza para generar un mensaje de saludo para los datos recibidos del controlador.

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

Inicie el servidor usando la caja de cambios

gearbox serve –reload –debug

Invoque el controlador macro () ingresando la siguiente URL en el navegador:

http://localhost:8080/macro

La siguiente salida se renderizará en el navegador:

py: con

Esta directiva le permite asignar expresiones a variables locales. Estas variables locales hacen que la expresión interna sea menos detallada y más eficiente.

Suponiendo que x = 50 se da en datos de contexto para una plantilla, el siguiente será el py: con directiva -

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

Dará como resultado la siguiente salida:

50 50 100

También está disponible una versión alternativa para py: con directiva -

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

En el siguiente ejemplo, el controlador macro () devuelve un objeto dict con teclas de nombre, phy y matemáticas.

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}

La plantilla macro.html agrega valores de claves phy y matemáticas usando py: con directiva.

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

El navegador mostrará el siguiente resultado en respuesta a la URL http://localhost:8080/macro

Directivas de manipulación de estructuras

los py:attrs La directiva agrega, modifica o elimina atributos del elemento.

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

Si foo = {‘class’:’collapse’} está presente en un contexto de plantilla, que se mostrará en el fragmento anterior.

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

los py:content La directiva reemplaza cualquier contenido anidado con el resultado de evaluar la expresión -

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

Dado bar = 'Bye' en los datos de contexto, esto produciría

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

los py:replace La directiva reemplaza el elemento en sí con el resultado de evaluar la expresión -

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

Dado bar = 'Bye' en los datos de contexto, produciría

<div>
   Bye
</div>