Turbogears-genshi-template-language

提供:Dev Guides
移動先:案内検索

TurboGears-Genshiテンプレート言語

Genshiは、XMLベースのテンプレート言語です。 TurboKearsの以前のバージョンのテンプレートエンジンであった Kid に似ています。 GenshiとKidは、 HSLT、TALPHP などの他の有名なテンプレート言語に触発されています。

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ディレクティブを列挙します-

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

条件付きセクション

Genshiは、コンテンツの条件付きレンダリングのための2つのディレクティブpy:ifおよびpy:chooseを提供します。

py:if

このディレクティブの要素のコンテンツは、* 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:choose

*py:choose* を *py:when* および *py:otherwise* ディレクティブと組み合わせて使用​​すると、高度な条件付き処理が可能です。 この機能は、 *C/C ++* の *switch – case* コンストラクトに似ています。
*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フォームは/marks URLにデータを投稿します。 * marks()関数はマークをリダイレクトし、辞書オブジェクトの形式で結果を *totall テンプレートにリダイレクトします。 result Pass/Fail の条件付き表示は、 py:choose および py:when ディレクティブを使用して実現されます。

マークを入力するHTMLスクリプト( marksl )は次のとおりです-

<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()*コントローラはマークと結果を *totall* テンプレートに送信しています-
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

テンプレートフォルダーの totall は辞書データを受け取り、次のように条件付きで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ディレクティブを使用してtotallテンプレートでレンダリングされた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})

templテンプレートは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>

次の例では、 root.py の* macro()コントローラーが、name1とname2の2つのキーを持つ *dict オブジェクトをmacrolテンプレートに送信します。

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

このマクロテンプレートには、グリーティングと呼ばれるマクロの定義が含まれています。 コントローラから受信したデータのグリーティングメッセージを生成するために使用されます。

<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()コントローラーは、名前、phy、および数学キーを持つ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}

テンプレートmacrolは、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:for Example

構造操作ディレクティブ

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