Учебники

TurboGears — Genshi Template Language

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 будет отображать следующий вывод —

Всего 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 / макро

Следующий вывод будет отображен в браузере —

Пример Def

ру: с

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

Предполагая, что 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: например

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

Директива 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’,