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