TurboGears - język szablonów Genshi

Genshi to język szablonów oparty na XML. To jest podobne doKid, który był kiedyś silnikiem szablonów dla wcześniejszych wersji TurboGears. Genshi i Kid są inspirowane innymi znanymi językami szablonów, takimi jakHSLT, TAL i PHP.

Szablon Genshi składa się z dyrektyw przetwarzania. Te dyrektywy są elementami i atrybutami w szablonie. Dyrektywy Genshi są zdefiniowane w przestrzeni nazwhttp://genshi.edgewall.org/. Dlatego ta przestrzeń nazw musi być zadeklarowana w głównym elemencie szablonu.

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

Powyższa deklaracja oznacza, że ​​domyślna przestrzeń nazw jest ustawiona na XHTML, a dyrektywy Genshi mają przedrostek „py”.

Dyrektywy Genshi

W Genshi zdefiniowano szereg dyrektyw. Poniższa lista wylicza dyrektywy Genshi -

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

Sekcje warunkowe

Genshi dostarcza dwie dyrektywy warunkowego renderowania treści - py: if i py: choose.

py: jeśli

Zawartość elementu tej dyrektywy będzie renderowana tylko wtedy, gdy wyrażenie w if clausezwraca wartość true. Zakładając, że dane w kontekście szablonu to{‘foo’:True, ‘bar’:’Hello’}, następująca dyrektywa -

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

spowoduje

Hello

Te dane wyjściowe nie byłyby jednak renderowane, gdyby ‘foo’ is set to False.

Ta dyrektywa może być również używana jako element. W tym przypadku<py:if> musi być zamknięty przez odpowiednie </py:if>

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

py: wybierz

Zaawansowane przetwarzanie warunkowe jest możliwe dzięki wykorzystaniu py:choose w połączeniu z py:when i py:otherwisedyrektyw. Ta funkcja jest podobna doswitch – case skonstruuj w C/C++.

Wyrażenie w py:choose Dyrektywa jest sprawdzana z różnymi wartościami oznaczonymi py:whenzostaną wyrenderowane alternatywy i odpowiadające im treści. Domyślną alternatywę można dostarczyć w postacipy:otherwise dyrektywa.

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

Poniższy przykład ilustruje użycie py:choose i py:whendyrektyw. Formularz HTML wysyła dane do / zaznacza adres URL. Plikmarks() funkcja przekierowuje znaki i wyniki w postaci obiektu słownika do total.htmlszablon. Warunkowe wyświetlanieresult Pass/Fail osiąga się za pomocą py:choose i py:when dyrektyw.

Skrypt HTML do wprowadzania znaków (marks.html) wygląda następująco -

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

Pełny kod root.pynastępująco. Plikmarks() kontroler wysyła oceny i wyniki do total.html szablon -

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

Plik total.html w folderze szablonów otrzymuje dane ze słownika i warunkowo analizuje je w danych wyjściowych html w następujący sposób -

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

Uruchom serwer (jeśli jeszcze nie działa)

Gearbox server –reload –debug

Wchodzić http://localhost::8080/marksform w przeglądarce -

Plik total.html wyrenderuje następujące wyjście -

py: dla

Element w dyrektywie py: for jest powtarzany dla każdego elementu w iterowalnym obiekcie, zazwyczaj w obiekcie Python List. Gdybyitems = [1,2,3] jest obecny w kontekście szablonu, można go iterować, wykonując następujące polecenie py: dla dyrektywy -

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

Zostanie wyrenderowany następujący wynik -

1
2
3

Poniższy przykład pokazuje dane formularza HTML renderowane w szablonie total.html przy użyciu dyrektywy py: for, które mogą być również użyte w następujący sposób -

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

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

Plik loop() kontroler odczytuje dane z formularza i przesyła je do total.template w postaci obiektu listy.

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

Szablon temp.html używa pętli py: for do renderowania zawartości obiektu dict w postaci tabeli.

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

Uruchom serwer (jeśli jeszcze nie działa)

gearbox server –reload –debug

Wchodzić http://localhost::8080/marksform w przeglądarce.

Poniższe dane wyjściowe zostaną wyświetlone w przeglądarce po przesłaniu powyższego formularza.

py: pok

Ta dyrektywa służy do tworzenia makra. Makro to fragment kodu szablonu wielokrotnego użytku. Podobnie jak funkcja Pythona ma nazwę i opcjonalnie może mieć parametry. Wyjście tego makra można wstawić w dowolnym miejscu szablonu.

Dyrektywa py: def ma następującą składnię -

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

To makro może być renderowane z wartością zmiennej w parametrze „nazwa”.

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

Tej dyrektywy można również używać z inną wersją składni w następujący sposób -

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

W poniższym przykładzie macro() kontroler w root.py wysyła dict obiekt z dwoma kluczami nazwa1 i nazwa2 do szablonu 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'}

Ten szablon macro.html zawiera definicję makra o nazwie powitanie. Służy do generowania powitania dla danych odebranych z kontrolera.

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

Uruchom serwer za pomocą gearboxa

gearbox serve –reload –debug

Wywołaj kontroler makra (), wprowadzając następujący adres URL w przeglądarce -

http://localhost:8080/macro

Następujące dane wyjściowe zostaną wyrenderowane w przeglądarce -

py: z

Ta dyrektywa umożliwia przypisywanie wyrażeń do zmiennych lokalnych. Te zmienne lokalne sprawiają, że wyrażenie wewnątrz jest mniej szczegółowe i wydajniejsze.

Zakładając, że x = 50 podano w kontekście danych dla szablonu, poniżej będzie py: z dyrektywą -

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

Spowoduje to następujący wynik -

50 50 100

Dostępna jest również wersja alternatywna dla py: with z dyrektywą -

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

W poniższym przykładzie kontroler macro () zwraca obiekt dict z kluczami nazwy, phy i matematyki.

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}

Szablon macro.html dodaje wartości kluczy phy i matematycznych za pomocą dyrektywy 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>

Przeglądarka wyrenderuje następujące dane wyjściowe w odpowiedzi na adres URL http://localhost:8080/macro

Dyrektywy dotyczące manipulacji strukturą

Plik py:attrs Dyrektywa dodaje, modyfikuje lub usuwa atrybuty z elementu.

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

Gdyby foo = {‘class’:’collapse’} jest obecny w kontekście szablonu, który zostanie wyrenderowany przez powyższy fragment.

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

Plik py:content Dyrektywa zastępuje zagnieżdżoną zawartość wynikiem oceny wyrażenia -

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

Biorąc pod uwagę słupek = „Bye” w danych kontekstowych, dałoby to

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

Plik py:replace dyrektywa zastępuje sam element wynikiem oceny wyrażenia -

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

Biorąc pod uwagę słupek = „Do widzenia” w danych kontekstowych, to wygeneruje

<div>
   Bye
</div>