なんたらノート第三期ベータスマートフォン用の表示で見るなんたらノート第三期ベータこの広告は、90日以上更新していないブログに表示しています。2008-07-24複合的なKidテンプレートPythonこのエントリは2007/10/06の再掲ですTurboGearsの標準テンプレートエンジン、Kidの説明です。quickstartで作成されたwelcome.kidとmaster.kidを見てみると、本当に初めてでは、どういう理屈で組み合わされてページが作られているのかさっぱりわかりません。そこで、少し詳しくメモを残しました。TapestoryのPython版です。実行イメージはJSPです。実行イメージでいえば、Javaサーブレットに対するJSPがそうであるように、Kidはテンプレート言語というよりも、むしろPythonコードの別の書き方だといえるでしょう。それだけではありません。KidはもっともっとPython的です。どんなに固定的な設定でも、それらはPythonコードで記述されるのです。スクリプトレットだけが危険なネイティブコードで、他は安全なタグライブラリと式言語、というわけではありません。テンプレート言語で書かれたソース全体がプログラムコードになります。ページデザイナーは暗黙的にプログラムしているのです。つねにスクリプトが逐次処理される動作イメージを持たなければなりません。じっさい、­Kidのコンパイル結果はpycになり、構文エラーは例外とスタックトレースを吐きます。テンプレートファイルはひとつの関数に見立てることができます。Kidレンダラに与えられたマップオブジェクトは、その関数に与えられたキーワード引数として展開されます。関数内に定義された関数から、ローカル変数をレキシカルに参照できるように、Kidもまた、その内部のいかなる箇所からでも、もっとも外側の関数の引数を参照できます。それとは別に、特別な変数があります。それが、今回の本題である、item変数です。個々の要素(XMLでいう要素のこと、DOM系のAPIではElementクラスに相当)をレンダリングするとき、要素は一時的にitem変数に格納されます。py:match属性を持つ要素(以下マッチング置換要素と呼ぶ)をひとつでも書いていると、ここで、すべてのマッチング置換要素について、繰り返しpy:match内の式が評価されます。評価対象は当然、「現在処理しようとしている要素」を指すitem変数です。どんな式を書くとよいかはともかく、評価結果が真を返すと、本来その場に展開されるはずの要素であるitem変数はローカルスコープに保持されたままになり、入れ替わりで、マッチング置換要素のレンダリングが始まります。マッチング置換要素をレンダリングするとき、item変数がスコープに保持されたままになっているということは...。マッチング置換要素の中で、このオリジナル要素構造をレンダリングすれば、オリジナル文書で割り込みをいっさい想定しなくても、より賢い他者がその外から、関心のある部分を探し出してくれ、元の処理を尊重したまま、任意の処理を飾り付けることができるのです。「賢い他者」が、凡庸なすべてのコードの面倒を見てくれて、横断的に関心事を挿入してくれる...、つまり、アスペクト指向です。マッチ条件はポイントカットの記述方法、マッチング置換要素の中身はアドバイスと考えると、py:matchをもっとも的確に理解できるでしょう。単独でレンダリング可能なKidファイルでいいので、以下ように記述してレンダリングしてみましょう。#2〜だけが、py:matchを持つ要素でデコレーションされました。itemをレンダリングに使っています。残念ながら、入門ドキュメントにはあまり詳しいitem変数(というよりElementクラス)の仕様がありません。次にとるべき、もっともPython的な行動は、「だいたいわかったら、dirで覗いて片っ端から使ってみる」ですね。#3</div>片っ端から使いました(笑)。itemはシーケンスに見えるオブジェクトで、かつ、マップに見えるオブジェクトでもあるようです。シーケンスとして見れば子要素の列で、マップとして見れば属性の辞書としてふるまいます。そのどちらからも、自分自身をあらわす十分な値は見えません。自分自身についての情報は、オブジェクトの属性にアクセスします。使い勝手についてまとめると、こんな感じでしょうか。item[:]は、元の要素の中身だけを再現するこれだけわかれば、十分に使えるんじゃないでしょうか?ちょっと変わっているのは、item.textです。Kidの基本は要素のツリーで、ノードのツリーではありません。最初の子要素までの間に挟まっているテキストノードは、その要素のオマケとしてtext属性に入るようです。W3C的じゃなくて素敵。アスペクト指向できることはわかったものの、隣り合った場所にアスペクトを置いても仕方ありません。実装コードとアスペクトを分離できないものでしょうか?それには、折り込みする者とされる者の関係の方向によって、2種類の選択肢が準備されています。py:layoutです。py:extendsを要素に付け加えると、指定したファイルに入っているマッチング置換要素が、自分のドキュメントにアスペクトを折り込んでくれます。「CSSやJavaScriptのリンクを、必要に応じて要るものだけ入れてくれる」なんていうアスペクトは、まさに横断的関心事ですね。ちなみにpy:extendsには、複数のファイルを指定することができます。py:layoutはその逆で、指定した基本ファイルに対して、自分のほうからマッチング置換要素を用いてアスペクトを折り込み、その基本ファイルのドキュメントを操作して結果を得る方法です。レイアウトデザインされた静的なHTMLに、外から動的ページ要素を入れ込むことが可能です。たしかに、py:matchは少し高度ですが、ちょっとその高度さを乗りこなせさえすれば、他のすべての仕事が、普通よりもぐんと楽になります。いやぁ、やっぱりPython文化は、専門のナントカ技術を勉強した人のものではなく、ハッカーと普通の人に嬉しい文化ですね。そりゃあ、GoogleがサラリーマンPGを排除するのに使うわけだ(笑)。(1)月別アーカイブはてなブログをはじめよう!tanakahisateruさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。