TurboGears-Genshiテンプレート言語
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ではいくつかのディレクティブが定義されています。次のリストはGenshiディレクティブを列挙しています-
- py:if
- py:choose
- py:for
- py:def
- py:match
- py:with
- py:replace
- py:content
- py:attrs
- py:strip
条件付きセクション
Genshiは、コンテンツの条件付きレンダリング用にpy:ifとpy:chooseの2つのディレクティブを提供します。
py:if
このディレクティブの要素の内容は、次の式の場合にのみレンダリングされます。 if clausetrueと評価されます。テンプレートコンテキストのデータが{‘foo’:True, ‘bar’:’Hello’}、次のディレクティブ-
<div>
<b py:if = "foo">${bar}</b>
</div>
結果として
Hello
ただし、この出力は次の場合にはレンダリングされません。 ‘foo’ is set to False。
このディレクティブは要素としても使用できます。この場合<py:if> 対応することによって閉じる必要があります </py:if>
<div>
<py:if test = "foo">
<b>${bar}</b>
</py:if>
</div>
py:choose
高度な条件付き処理は、 py:choose と組み合わせて py:when そして py:otherwiseディレクティブ。この機能はに似ていますswitch – case で構築する C/C++。
での表現 py:choose ディレクティブは、で識別されるさまざまな値でチェックされます py:when代替と対応するコンテンツがレンダリングされます。デフォルトの代替は、次の形式で提供できます。py:otherwise 指令。
<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フォームはデータを/ marksURLに投稿します。ザ・marks() 関数は、マークと結果を辞書オブジェクトの形式でにリダイレクトします total.htmlテンプレート。の条件付き表示result 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
py:forディレクティブの要素は、反復可能(通常はPython Listオブジェクト)の項目ごとに繰り返されます。場合items = [1,2,3] テンプレートコンテキストに存在する場合は、py:forディレクティブを実行することで繰り返すことができます-
<ul>
<li py:for = "item in items">${item}</li>
</ul>
次の出力がレンダリングされます-
1
2
3
次の例は、py:forディレクティブを使用してtotal.htmlテンプレートでレンダリングされたHTMLフォームデータを次のように使用できることを示しています。
<py:for each = "item in items">
<li>${item}</li>
</py:for>
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>
ザ・ 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 ブラウザで。
上記のフォームを送信すると、ブラウザに次の出力が表示されます。
py:def
このディレクティブは、マクロを作成するために使用されます。マクロは、テンプレートコードの再利用可能なスニペットです。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 macro.htmlテンプレートへのname1とname2の2つのキーを持つオブジェクト。
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テンプレートには、greetingと呼ばれるマクロの定義が含まれています。コントローラから受信したデータのグリーティングメッセージを生成するために使用されます。
<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
ブラウザに次のURLを入力してmacro()コントローラを起動します-
http://localhost:8080/macro
以下の出力がブラウザに表示されます-
py:with
このディレクティブを使用すると、ローカル変数に式を割り当てることができます。これらのローカル変数により、内部の表現がより冗長で効率的になります。
テンプレートのコンテキストデータで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()コントローラーは、name、phy、およびmathsキーを持つdictオブジェクトを返します。
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は、py:withディレクティブを使用してphyキーとmathsキーの値を追加します。
<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'を指定すると、次のようになります。
<div>
Bye
</div>