Genshi — это язык шаблонов на основе XML. Он похож на Kid , который раньше был движком шаблонов для более ранних версий TurboGears. Genshi и Kid вдохновлены другими известными языками шаблонов, такими как 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. Следующий список перечисляет директивы Genshi —
- ру: если
- ру: выбрать
- ру: для
- р: Защита
- ру: матч
- ру: с
- ру: заменить
- ру: содержание
- ру: ATTRS
- ру: полоса
Условные разделы
Genshi предоставляет две директивы для условного рендеринга контента — py: if и py: select.
ру: если
Содержимое элемента этой директивы будет отображено, только если выражение в условии if оценивается как true. Предполагая, что данные в контексте шаблона: {‘foo’: True, ‘bar’: ‘Hello’} , следующая директива —
<div>
<b py:if = "foo">${bar}</b>
</div>
приведет к
Hello
Однако этот вывод не будет отображаться, если для ‘foo’ установлено значение False .
Эта директива также может быть использована в качестве элемента. В этом случае <py: if> должен быть закрыт соответствующим </ py: if>
<div>
<py:if test = "foo">
<b>${bar}</b>
</py:if>
</div>
ру: выбрать
Расширенная условная обработка возможна с использованием py: выбрать в сочетании с директивами py: when и py: else. Эта функция похожа на конструкцию switch-case в C / C ++ .
Выражение в py: директива Choose проверяется с различными значениями, идентифицированными с py: когда будут отображаться альтернативы и соответствующее содержимое. Альтернатива по умолчанию может быть предоставлена в форме директивы py: else.
<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-форма отправляет данные на / mark URL. Функция marks () перенаправляет метки и результаты в виде объекта словаря в шаблон total.html . Условное отображение результата 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: 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 Form Script
<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 в браузере.
При отправке вышеуказанной формы в браузере будет отображаться следующий вывод.
р: Защита
Эта директива используется для создания макроса. Макрос — это многократно используемый фрагмент кода шаблона. Как и функция 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: // локальный: 8080 / макро
Следующий вывод будет отображен в браузере —
ру: с
Эта директива позволяет вам присваивать выражения локальным переменным. Эти локальные переменные делают выражение внутри менее многословным и более эффективным.
Предполагая, что 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’,





