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>