TurboGears - язык шаблонов Genshi

Genshi - это язык шаблонов на основе XML. Это похоже наKid, который раньше был механизмом шаблонов для более ранних версий TurboGears. Генши, а также Кид вдохновлены другими известными языками шаблонов, такими какHSLT, TAL и PHP.

Шаблон Genshi состоит из директив обработки. Эти Директивы являются элементами и атрибутами в шаблоне. Директивы Genshi определены в пространстве именhttp://genshi.edgewall.org/. Следовательно, это пространство имен необходимо объявить в корневом элементе шаблона.

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

Вышеупомянутое объявление означает, что пространство имен по умолчанию установлено на XHTML, а директивы Genshi имеют префикс py.

Директивы Генши

В Genshi определен ряд директив. В следующем списке перечислены директивы Генши -

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

Условные разделы

Genshi предоставляет две директивы для условного рендеринга контента - py: if и py: choose.

ру: если

Содержимое элемента этой директивы будет отображаться, только если выражение в if clauseоценивается как истина. Предполагая, что данные в контексте шаблона{‘foo’:True, ‘bar’:’Hello’}, следующая директива -

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

приведет к

Hello

Этот вывод, однако, не будет отображаться, если ‘foo’ is set to False.

Эта директива также может использоваться как элемент. В этом случае<py:if> должны быть закрыты соответствующими </py:if>

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

ру: выбрать

Возможна расширенная условная обработка с использованием py:choose в комбинации с py:when и py:otherwiseдирективы. Эта функция похожа наswitch – case построить в C/C++.

Выражение в py:choose директива проверяется с разными значениями, идентифицированными с py:whenальтернативы и соответствующее содержимое будут отображены. Альтернатива по умолчанию может быть предоставлена ​​в видеpy:otherwise директива.

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

В следующем примере показано использование py:choose и py:whenдирективы. HTML-форма отправляет данные в / отмечает URL. Вmarks() функция перенаправляет метки и результаты в виде объекта словаря на total.htmlшаблон. Условное отображениеresult Pass/Fail достигается за счет использования py:choose и py:when директивы.

HTML-скрипт ввода меток (marks.html) выглядит следующим образом -

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

Полный код root.pyкак следует. Вmarks() контроллер отправляет отметки и результат в total.html шаблон -

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

В total.html в папке шаблонов получает данные словаря и анализирует их в выводе html условно следующим образом:

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

Запустите сервер (если он еще не запущен)

Gearbox server –reload –debug

Войти http://localhost::8080/marksform в браузере -

В total.html отобразит следующий вывод -

py: для

Элемент в директиве py: for повторяется для каждого элемента в итерации, обычно это объект списка Python. Еслиitems = [1,2,3] присутствует в контексте шаблона, его можно повторить, выполнив следующую директиву py: for -

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

Будет отображен следующий вывод -

1
2
3

В следующем примере показаны данные HTML-формы, отображаемые в шаблоне total.html с использованием директивы py: for, также можно использовать следующим образом:

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

Скрипт 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>

В loop() Контроллер считывает данные формы и отправляет их в 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})

В шаблоне temp.html используется цикл py: for для визуализации содержимого объекта dict в виде таблицы.

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

Запустите сервер (если он еще не запущен)

gearbox server –reload –debug

Войти http://localhost::8080/marksform в браузере.

Следующий вывод будет отображаться в браузере при отправке формы выше.

py: def

Эта директива используется для создания макроса. Макрос - это многократно используемый фрагмент кода шаблона. Как и функция Python, у нее есть имя и, при желании, параметры. Вывод этого макроса можно вставить в любое место шаблона.

Директива py: def следует следующему синтаксису -

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

Этот макрос может быть отображен со значением переменной в параметре name.

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

Эту директиву также можно использовать с другой версией синтаксиса следующим образом:

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

В следующем примере macro() контроллер в root.py отправляет dict объект с двумя ключами name1 и name2 к шаблону 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'}

Этот шаблон macro.html содержит определение макроса, называемого приветствием. Он используется для генерации приветственного сообщения для данных, полученных от контроллера.

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

Запустите сервер с помощью коробки передач

gearbox serve –reload –debug

Вызовите контроллер macro (), введя следующий URL-адрес в браузере -

http://localhost:8080/macro

Следующий вывод будет отображаться в браузере -

py: с

Эта директива позволяет назначать выражения локальным переменным. Эти локальные переменные делают выражение внутри менее подробным и более эффективным.

Предполагая, что x = 50 задано в данных контекста для шаблона, далее будет директива py: with -

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

Это приведет к следующему выводу -

50 50 100

Также доступна альтернативная версия для директивы py: with -

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

В следующем примере контроллер macro () возвращает объект dict с ключами name, phy и 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}

Шаблон macro.html добавляет значения ключей phy и maths с помощью директивы py: with.

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

Браузер отобразит следующий вывод в ответ на URL-адрес http://localhost:8080/macro

Директивы по манипулированию структурой

В py:attrs Директива добавляет, изменяет или удаляет атрибуты элемента.

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

Если foo = {‘class’:’collapse’} присутствует в контексте шаблона, который будет отображать приведенный выше фрагмент.

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

В py:content Директива заменяет любой вложенный контент результатом вычисления выражения -

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

Если в данных контекста bar = 'Bye', это приведет к

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

В py:replace Директива заменяет сам элемент результатом вычисления выражения -

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

Если в данных контекста bar = 'Bye', это приведет к

<div>
   Bye
</div>