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>