KidでHTMLを部品化する
Ploneを[使いこなしている]人向けに簡単に解説すると,「KidでZPTのslotみたいなことを実現する方法」。
オブジェクト指向を知っている向けに簡単に説明すると,「Kidのテンプレートを使って,テンプレートの継承とメソッドの継承みたいなことを実現する方法」。
これから解説することについて,もうちょっと長い説明。
- マスターテンプレートがあります
- マスターテンプレートには,表示する場所などによって異なった情報を埋め込みたい「部分(パートAと呼びます)」があります
- マスターテンプレートを「使う」側のサブテンプレートで,「パートAにはこの内容を埋めてね」と指定したいとします
このようなことを実現するための方法について解説します。本当はXMLの名前空間なんかも定義しないとならないんですが,冗長なのでこの解説では省いています。
以下のようなマスターテンプレート(master.kid)があるとします。
<html>
<body>
この部分は マスターテンプレートの本文です。
<div id="content"
py:for="elem in [ x for x in item.getchildren() if x.tag.endswith('}div') and x.get('id') == 'content']">
この部分にはサブテンプレートで指定した内容が埋め込まれます。
<span py:replace="elem[:]" />
</div>
</body>
</html>
サブテンプレート(sub.kid)は,以下のように定義します。
<html py:extends="path/to/master.kid">
<body>
<div id='content'>
** この部分がマスターテンプレートに埋め込まれます。 **
</div>
</body>
</html>
サブテンプレートの出力結果は,以下のようになります。
<html>
<body>
この部分は マスターテンプレートの本文です。
<div id="content">
** この部分がマスターテンプレートに埋め込まれます。 **
</div>
</body>
</html>
要は,サブテンプレートでidを振ったdivの領域を入れ替えることが出来るわけね。サイトワイドで定義したいデザインなんかはマスター側で定義しておいて,本体部分とかボートレットみたいなのはサブテンプレートで「継承」できるわけです。メインテンプレート側で「バーチャルな」部分を定義し,サブテンプレート側で継承して置き換えるわけですな。
Kidのテンプレート内部ではElementTreeのElementオブジェクトを使えるんだけど,このことを利用したテクニック。この方法を使うと,テンプレートをXHTML validに保ったままHTMLが部品化できるのです。
TurboGearsのマスターテンプレートでは,似た方法を使ってbodyの中身だけをサブテンプレートの内容に置き換えています。
うーん,難しいかな。
- Category(s)
- python
- The URL to Trackback this entry is:
- http://coreblog.org/ats/make-a-parts-using-kid/tbping


これって、サブテンプレートで上書きしなかった場合にはどういう出力になるんでしょう?
ZPTのドキュメントもですが、コード例がAbstractをImplementsしている説明に感じられてしまうのですが。
>everesさん
ZPTのslotにはデフォルトの状態を埋め込むことができますのでabstructでないvirtualな部分としてslotを利用できます。
slotをfillしないとデフォルトが適用されます。からのエレメントをfillするとslot自体を消すことができます。
Kidの例は,ElementTreeを使ってテンプレート自体に継承の機能を実装してあります。
なので,abstructでないvirtualな部品を設置したければそういう実装にすればいいだけの話です。
ZPTはテンプレートとしては歴史がありますし,事例も他と比較してものすごく多いです。
テンプレートの一部をメタなテンプレートとして定義して外部から呼び出したりと,とにかく気の利いた機能がたくさんあります
KidはZPTのよいところを取り込んでいて,かつPHPのような埋め込みの記法もサポートしているところが魅力ですね
なによりどっちもXHTML validな状態を保ったままテンプレートを記述できるのが良い点だと思います
ZPTは、なんだか凄そうですね。Ploneの圧倒的なテンプレート群の前に、いつも諦めてしまっていました。
いつの日か、深くさわってみたいと思います。
ありがとうございました。