テンプレートシステムは、動的に HTML ページを生成する方法のひとつです1。 具体的には、テンプレートとなる HTML ファイルをメインプログラムから読み込み、必要な箇所を書き換えて出力するという仕組みのことです。 またこれを実現してくれる具体的なライブラリをテンプレートエンジンといいます。
前回は、動的に HTML ページを生成する方法について、テンプレートシステムも含めて 3 つ紹介しました。 またそれぞれの方法において、テキスト汎用型と HTML 専用型の 2 つのタイプがあることも紹介しました。
今回は、テンプレートシステムについて詳しく見ていきます。 具体的には、次のことについて説明します。
なお本稿の対象読者は、Web アプリケーション開発に興味のある方です。 特に、テンプレートシステムを自作しようと考えている方や、Web デザイナーとの協業を考えておられる方には、とりわけ参考になると思います。
何らかの表示を伴うアプリケーションは、大きく「ビジネス層」と「プレゼンテーション層」の 2 つに分けることができます2。
仕組みとしては、ビジネス層であるメインプログラムがデータを用意し、それをプレゼンテーション層であるテンプレートシステムに渡すことでデータが表示されます (図 1)。
図 1. ビジネス層とプレゼンテーション層
またビジネス層とプレゼンテーション層それぞれに、ロジックとデータが必要です (表 1)。 これらはそれぞれ、ビジネスロジック、ビジネスデータ、プレゼンテーションロジック、プレゼンテーションデータといいます。
表 1: ビジネス層とプレゼンテーション層のそれぞれにロジックとデータがある
ビジネス層 | プレゼンテーション層 | |
---|---|---|
ロジック | ビジネスロジック | プレゼンテーションロジック |
データ | ビジネスデータ | プレゼンテーションデータ |
たとえば、「営業部員の売り上げ成績から上位 20 名を選出し、奇数行と偶数行で背景色を変えて <table> タグで表示する」というアプリケーションを考えると、これは次のように分解できます。
ここで大事なのは、__プレゼンテーション層にもロジックが必要である__ということです。 この例でいうと、「奇数行と偶数行で背景色を変える」というのは表示のためだけに必要なロジックであり、明らかにプレゼンテーション層に含まれます。 これをビジネス層であるメインプログラムに含めてはいけません。
よく「ロジックとプレゼンテーションを分離する」という人がいますが、これは誤りです。 なぜなら、プレゼンテーション層にもロジックが含まれるからです。 「ビジネス層とプレゼンテーション層を分離する」や「プレゼンテーション層をプレゼンテーションロジックとプレゼンテーションデータに分離する」というなら正しいですが、「ロジックとプレゼンテーションを分離する」は明らかに間違いですので注意してください。
プレゼンテーション層が、プレゼンテーションロジックとプレゼンテーションデータに分けられることはわかりました。 また HTML がプレゼンテーションデータであることは明白です。 では、プレゼンテーションロジックはどこに記述すべきでしょうか。
実は、これこそがテンプレートシステムにおける重要ポイントです。 プレゼンテーションロジックをどこに記述するかで、テンプレートの HTML デザインが崩れるか否か、またデザイナーとプログラマーとが協業しやすいかどうかが決まります。
プレゼンテーションロジックを記述する場所は、3 つ考えられます (図 2)。
図 2. プレゼンテーションロジックを記述する場所
これらを詳しく見ていきます。
現在ほとんどのテンプレートエンジンは、プレゼンテーションロジックを HTML テンプレート中に記述しています。例を挙げると、Ruby でいえば eRuby、Tempura、Tenjin など、Ruby 以外でいえば Velocity(Java)、Smarty(PHP)、Template-Toolkit(Perl)、Zope PageTemplate(Python) などが挙げられます。
プレゼンテーションロジックを HTML テンプレートの中に記述するのは、方法としては分かりやすいのですが、HTML の中に HTML ではない要素 (= プレゼンテーションロジック) が混じるため、記法を工夫しないと HTML デザインが崩れてしまいます3。 また Web デザイナーと協業する場合、デザイナーとプログラマーが同じファイルを編集するため、同時作業がしづらく、またデザイナーが誤ってロジックを変更してしまう危険性もあり、協業するには都合が悪いです。
例として、Tenjin のサンプルをリスト 1 と リスト 2 に掲載します。 ビジネス層 (メインプログラム) とプレゼンテーション層 (テンプレート) はきれいに分離していますが、テンプレートの中にプレゼンテーションデータとプレゼンテーションロジックが混在していることが分かります。 そのため、デザイナーが誤ってプレゼンテーションロジックを変更してしまう可能性は十分にあります。
また Tenjin のように処理命令を使ったり、Tempura や Zope PageTemplate のようにタグの属性に記述する場合は HTML デザインが崩れませんが、たとえば eRuby のように「<% %>」を使ったり、Velocity のように独自記法を採用している場合は、テンプレートの HTML デザインが崩れてしまうため、デザイナーには不評です。
リスト 1: ex-tenjin.rbhtml (テンプレート)
リスト 2: ex-tenjin.rb (メインプログラム)
プレゼンテーションロジックをメインプログラム中に記述することで、HTML テンプレートに余計なものが含まれないようにしたテンプレートシステムがあります。例を挙げると、Ruby なら Amrita2 や misen、Ruby 以外だと Enhydra XMLC(Java) や Wicket4(Java) が挙げられます。
プレゼンテーションロジックをメインプログラムの中に書く方法は、HTML テンプレートの中に余計なものが混じらないので HTML デザインが崩れません。 またデザイナーが編集するファイル (= HTML テンプレート) と、プログラマーが編集するファイル (= メインプログラム) が別になるので、同時作業がしやすく、デザイナーがロジックを触ることができないので、デザイナーと協業する上でも好都合です。
しかし、本来プレゼンテーション層に含まれるべきプレゼンテーションロジックが、ビジネス層を担当するメインプログラムに現れるわけですから、ビジネス層とプレゼンテーション層が分離できません。 アプリケーションのアーキテクチャとしては良くないです。
例として、Amrita2 のサンプルをリスト 3 とリスト 4 に掲載します。 テンプレート中に HTML 以外の要素 (= プレゼンテーションロジック) が現れておらず、テンプレートのデザインがまったく崩れないことがわかります。
しかしプレゼンテーションロジックがメインプログラム中に現れるため、ビジネス層とプレゼンテーション層とが分離できていないこともわかります (Amrita2 ではロジックをデータで表現するため、Amrita2 用にデータを用意することがプレゼンテーションロジックの記述になります)。
リスト 3: ex-amrita2.html (テンプレート)
リスト 4: ex-amrita2.rb (メインプログラム)
ただこのタイプの場合、プレゼンテーションロジックをメインプログラムから追い出して別ファイルにすることはさほど難しくないため、あまり問題とはならないようです。 たとえば Amrita2 の場合、リスト 5 と リスト 6 のようにすれば、メインプログラムとプレゼンテーションロジックとを分離することができます。
リスト 5: ex-amrita2-view.rb (プレゼンテーションロジック)
リスト 6: ex-amrita2-main.rb (メインプログラム)
なお筆者の印象だと、このタイプのテンプレートシステムはどれも、複雑なプレゼンテーションロジックが記述しにくい (または分かりづらい) です。
プレゼンテーションロジックをテンプレート中に記述するのも、またメインプログラム中に記述するのも、どちらも問題があることが分かりました。 ではどうすればいいのでしょうか。
いちばん理想的なのは、プレゼンテーションロジックだけを別ファイルにすることです。 つまり、プレゼンテーション層を「HTML テンプレートファイル」と「プレゼンテーションロジックファイル」の 2 つに分離するわけです。
これによる利点は次の通りです。
このように、今まであった問題点がきれいに解決されていることがわかります。 また、特にデザイナーとプログラマーとの協業に向いていることも分かります。 欠点があるとすれば、ファイルの数が増えるので管理の手間が少し増えることぐらいでしょうか。
このタイプの例として、Kwartz のサンプルをリスト 7、8、9 に掲載します。 これをみると、テンプレートの HTML デザインがまったく崩れないことと、ビジネス層であるメインプログラムとプレゼンテーション層とがきれいに分離できていることがわかります。
Kwartz では、プレゼンテーションロジックをあたかも CSS のように記述します。 ちょうど、CSS によって HTML からデザインに関する事項を別ファイルに分離したように、Kwartz を使うと HTML からプレゼンテーションロジックを別ファイルに分離できます。 しかも、Kwartz はHTML 専用型のように見えて実はテキスト汎用型であり、HTML や XML 以外でも使用できます。
リスト 7 : ex-kwartz.html (テンプレート)
リスト 8 : ex-kwartz.plogic (プレゼンテーションロジック)
リスト 9 : (メインプログラム)
このタイプのテンプレートシステムは数が少ないですが、Ruby なら Kwartz や CGIKit、PHP なら Kwartz-php、Java なら Tapestry(Java)、Mayaa などがあります。
テンプレートシステムの特徴を考えるうえで、それらを分類してみるのはいい方法です。 分類方法はいくつも考えられますが、その中から筆者が重要だと思う分類方法を紹介します。
前のセクションで述べたように、プレゼンテーションロジックをどこに書くかによって、テンプレートシステムは次の 3 つに分類できます。
前のセクションと重複しますが、それぞれの特徴を以下にまとめます。
プレゼンテーションロジックをテンプレート中に書くタイプは、HTML 中に余計なものが混じるうえにデザイナーとプログラマーとが同じファイルを編集することになるため、協業するにはあまり向きません。だだ仕組みとしては分かりやすく学習コストも低いので、協業する必要がなければこのタイプでも問題ありません。
プレゼンテーションロジックをメインプログラムに書くタイプは、HTML に余計なものが混じることがなく、またデザイナーとプログラマーとで編集するファイルが異なるため、協業するには大変便利です。ビジネス層とプレゼンテーション層の分離という点では問題がありますが、プレゼンテーションロジックをメインプログラムから追い出すのは難しくないため、深刻な問題とはならないでしょう。それよりも、テンプレート中に書くタイプと比べて仕組みがわかりづらく、学習コストが大きい点のほうが問題となるでしょう。
プレゼンテーションロジックを独立したファイルに書くタイプは、デザイナーとプログラマーとが協業する上でも、またビジネス層とプレゼンテーション層の分離という点からも、いちばん理想的です。仕組みがわかりづらく学習コストがかかる点は、メインプログラムに書くタイプと同じです。このタイプの先駆けとなったのは WebObjects であり、WebObjects がコンポーネント指向であったためか、このタイプにはコンポーネント指向のフレームワークが多いです。
テンプレートシステムはまた、どんな形式を対象とするかによって、大きく以下の 2 種類に分類できます。
両者の特徴は互いに対の関係になっており、一方の利点は他方の欠点となっています。 以下にそれを紹介します。
テキスト汎用型は、テンプレート中に書く「目印」の記法が独自形式であることが多く、そのためテンプレートの HTML デザインが崩れます (本当は HTML のコメントや処理命令を「目印」として使ったり、Kwartz のように HTML タグを認識する独自のパーサを使うことで HTML デザインを崩さないようにできるのですが、そこまで考慮されたものは少ないです)。また HTML パーサや DOM ツリーを使わないので、HTML 専用型と比べて高速かつ軽量です。
HTML 専用型では、「目印」としてタグや属性を使うため、テンプレートの HTML デザインが崩れません。Amrita2 や XMLC のように id 属性で目印をつけるだけのものと、Tempura や Zope PageTemplate のように独自属性を使ってロジックを記述するものに分かれます5。また foreach ~ end や if ~ end のようなブロックは、HTML タグの構造をそのまま使います。内部で HTML パーサや DOM ツリーを使うため、一般的にはテキスト汎用型と比べて遅くかつ重いです。
以上のことから、テンプレートシステムは、
に分類できることが分かりました。 実際にはこれらの組み合わせになるので、3 * 2 = 6 種類に分類できます。
表 2 に、いくつかのテンプレートシステムを分類してみました。 テンプレートエンジンを選ぶときの参考にしてください。
表 2 : テンプレートシステムの分類
プレゼンテーションロジックを書く場所 | テキスト汎用型 | HTML 専用型 |
---|---|---|
テンプレート | Tenjin, Velocity, Smarty, Template-Toolkit, Cheetah | Tempura, Zope PageTemplate, Kid, Genshi |
メインプログラム | - | Amrita2, XMLC, Wicket |
独立した別ファイル | Kwartz | CGIKit, Tapestry6, Mayaa |
テンプレートシステム導入の効果として、デザイナーとプログラマーとの協業がしやすくなることが挙げられます。 しかし、実際にはうまく協業できている例はほとんどありません。
このセクションでは、デザイナーとプログラマーが協業するために何が必要か、筆者の見解を述べてみます。
デザイナーとプログラマーが本当の意味で協業するためには、__HTML テンプレート中にプレゼンテーションロジックを埋め込まないことが重要__です。
一般的に、デザイナーとプログラマーが協業するためには HTML テンプレートのデザインが崩れないことが大事だと言われます。 しかし筆者は、__HTML テンプレートのデザインが崩れないことは協業のための必要条件であって十分条件ではない__と考えています。 それよりも、HTML テンプレート中にプレゼンテーションロジックを埋め込まないことのほうが重要です。
リスト 10 をご覧下さい。 これは HTML デザインを崩さないことを特徴とする Kid という Python 用テンプレートエンジンのサンプルです。 これを見ると、プレゼンテーションロジックを属性に記述しているため、HTML デザインが崩れないことがわかります。
リスト 10 : Kid のテンプレート例 (HTML デザインが崩れない)
しかしこれだと、確かに HTML デザインは崩れていませんが、テンプレート中にプレゼンテーションロジックが埋め込まれているため、次のような問題が発生します。
大事なのは、これらの問題が、HTML テンプレートのデザインが崩れる崩れないに関わらず、プレゼンテーションロジックをテンプレートに埋め込むタイプのものであれば必ず発生するということです。
これらの問題を解決するには、プレゼンテーションロジックを HTML テンプレートから分離して別ファイルにするのがいい方法です。 つまり、Amrita2 のようにプレゼンテーションロジックをメインプログラムに書くタイプか、Kwartz のように完全な別ファイルに分離するタイプでないと、本当の意味での「プログラマーとデザイナーとの協業」は実現できません。
ただし、以上のことはあくまで技術的な観点からの見解です。 実際にデザイナーと協業するうえで本当に大事なのは、__デザイナーに対するリスペクト__ではないでしょうか。
本来であれば、デザイナーと協業しやすい仕組みを用意するのはプログラマーの責任です。 しかしその責任を果たさないくせに、デザイナーに「この書き方で書け」「ロジックぐらい書けるようになれ」と押しつける傲慢なプログラマーのなんと多いことでしょう。 ひどいのになると、「デザイナーって、HTML と絵を書いてるだけでしょ? あんなの誰でもできるよ」と言い出すプログラマーやプロマネもいます。
これはとんでもない暴言です。 素人が書く HTML とデザイナーが書く HTML とを同じだと思ってはいけません。 これは素人が書くプログラムと、お金をもらっているプログラマーが書くプログラムとを、「結局は同じプログラムでしょ?」といってしまうようなものであり、到底許されるものではありません。
プログラマーがコードに込める思いと同じだけのものを、デザイナーは HTML や CSS に込めています。 デザイナーが 1 ピクセルに見せるこだわりは、プログラマーがインデント幅にみせるこだわりよりもずっと尊いものです。 いくつもあるブラウザの互換性問題やバグを回避し、どのブラウザでも同じように表示されるように HTML や CSS を書くのは、素人では絶対に出来ない職人技です。 自分でいい仕事をしている人間は、他人のいい仕事もわかります。 他人の仕事のよさがわからないのは、自分がろくな仕事をしていない証拠です。
またプログラマーの皆さんが vi や Emacs や IDE ではなくメモ帳を使ってプログラムを書けと言われたらどう感じますか? デザイナーが Dreamweaver や GoLive を使えずエディタでテンプレートを書くことを強制されるのは、皆さんがメモ帳でプログラムを書くのを強制されるのと同じことなのです。 職人には職人の道具があります。 デザイナーという職人に対して、Dreamweaver や GoLive が使えないような、デザインが崩れっぱなしのテンプレートを使うよう強制するのはよくないことです。 プログラマーの都合をデザイナーに押し付けるべきではありません。
繰り返しますが、__デザイナーと協業しやすい仕組みを用意するのはプログラマーの責任__です。 もしみなさんがデザイナーとの協業を望むなら、まずはデザイナーの仕事を認めることが先であり、そのあとに彼らが作業しやすいテンプレートシステムを選びましょう。 テンプレートシステムが進化した今なら、それが可能なはずです。
テンプレートシステムに関する雑多な話題を紹介します。 本当に雑多ではありますが、自分でテンプレートシステムを自作しようと考えている方はぜひお読み下さい。損はさせません。
テンプレートシステムが、プレゼンテーションロジックを記述するための独自の言語を持つことがあります。 しかし、これは速度の面からも、また学習コストの面からも、やめたほうがいいです。
たとえば、Smarty や Template-Toolkit や Django や Velocity は、プレゼンテーションロジックを記述するために、独自の言語を用意しています。 しかし、これらは PHP や Perl や Python や Java をそのまま使うテンプレートシステムと比べて、以下のような欠点があります。
特に動作速度の問題は、皆さんが思っている以上に深刻です。 たとえば Perl でよく使われている Template-Toolkit はプレゼンテーションロジックを記述するのに独自言語を使いますが、C 言語で実装されているにも関わらず、pure Perl で実装された Tenjn と比べて動作は約 5 倍遅いです (Perl 用の Tenjin では Perl そのものをテンプレート言語として使います)。
このように、テンプレートシステム独自の言語を実装するのは、実装する側にも使う側にもメリットがありませんので、やめたほうがいいでしょう8。
HTML テンプレートをプログラマー以外の人が安全に編集できるようにしたいなら、プレゼンテーションロジックを HTML テンプレートから分離するタイプのテンプレートシステムを選ぶべきです。
テンプレートシステムの利点として、「テンプレート中に書けるロジックを制限できること」をあげる人がよくいます。 たとえばこちら:
> Smartyでも十分危険なコードはかけます
でも、制御することも可能なんですよね。(というか、それがすごく便利です) PHP直だと、「俺、HTMLコーダだけど、PHPも使えるぜ!PGに依頼せずに、自分で解決しておいてあげよう」 なんて、お節介な事されて、致命的なバグが発生したりするので、 別にSmartyに固執しなくてもいいのですが、HTMLコーダさんが勝手なことしないように制限かけて起きたいってのが 本音なんです。
しかし、これは大きな間違いです。 HTML にロジックを埋め込めるのであれば、どんなテンプレートシステムでも危険なことにかわりはありません。 独自言語を使うことで多少制限はできますが、大した違いはありません。
本当にテンプレートを安全に編集させようと思ったら、HTML テンプレート中には一切のロジックを記述できないようにすべきです。 つまり、Amrita2 や Wicket のように ロジックをメインプログラム中に記述するか、または CGIKit や Tapestry や Kwartz のようにロジックを別ファイルに分離するようにしなければいけません。
HTML テンプレート中にロジックが一切記述できないのであれば、デザイナーが何をしようと HTML テンプレートは安全です。 もっというと、デザイナーでない任意の人にも編集させることすらできるようになります。 たとえばブログサービスを展開していたとして、ユーザにブログの CSS だけでなく、HTML テンプレートの編集すら許可できるようになります (危険な Java スクリプトなどは、HTML テンプレートがアップロードされるときに削除すればよいでしょう)。
繰り返しますが、HTML テンプレートにロジックを記述できるのであれば、どのテンプレートシステムでも危険です。 安全に HTML テンプレートを編集させたいのであれば、プレゼンテーションロジックを HTML テンプレートから分離できるものを選びましょう。
プレゼンテーションロジックは、プレゼンテーション層に属します。 またプレゼンテーション層は「どう表示するか?」を表すため、デザイナーが担当するべきです。 このことから、三段論法でいうと、プレゼンテーションロジックはデザイナーの担当であるといえます。
たとえば、奇数行と偶数行で背景色を変えたテーブルがあるとします。 この「奇数行と偶数行で背景色を変える」というのはまさに表示のためのロジックであり、これをたとえば「金額がプラスかマイナスかで背景色を変える」に変更するとしたら、それを決定するのはプログラマーではなくデザイナーのはずです。 その意味では、「プレゼンテーションロジックはデザイナーの担当」というのは筋が通っています。
しかし実際には、プレゼンテーションロジックはプログラマーが担当したほうがいいでしょう。 なぜならプレゼンテーションロジックは、ビジネス層 (メインプログラム) からプレゼンテーション層 (テンプレートシステム) にどのようなデータが渡されるのかを知っていないと記述できず、それを知っているのはプログラマーだからです。
たしかに、見た目を管理するのはデザイナーの仕事です。 しかし、システムが正しく動作することのほうが見た目よりも重要です。 システムが正しく動作するうえで、ビジネス層からプレゼンテーション層にどんなデータが渡されるかは大変重要な情報であり、これについて責任を持つのはデザイナーではなくプログラマーです。 そのため、表示のためとはいえプレゼンテーションロジックはプログラマーが担当すべきというのが、筆者の考えです。 デザイナーがプレゼンテーションロジックを変更したくなったら、その都度プログラマーに頼むのがいいでしょう。
HTML エスケープとは、「< > & “」を「< > & "」に変換することです (サニタイズと呼ばれることもあります)。 これは Web アプリケーションを作る上で、セキュリティ上非常に大切なことです。 そのため、多くのテンプレートシステムでは HTML エスケープをする機能をサポートしています。
ただし、デフォルトで HTML エスケープするかどうかについては議論が分かれています。 最近では安全性を重視して、デフォルトで HTML エスケープするようなテンプレートシステムが出てきてはいますが、そうすると HTML 以外の用途では使いづらくなります。
また HTML エスケープしたくないときにどうするかという問題もあります。 たとえば ERB では <%= %> がデフォルトで HTML エスケープされるように改造することも可能なようですが、その場合は HTML エスケープしたくないときの指定が面倒になります。
いちばん手軽で効果が高いのは、HTML エスケープする記法としない記法の両方をテンプレートシステムが提供することです。 たとえば、<%= %> は HTML エスケープあり、<%== %> は エスケープなしにしたとします。 そうすれば、通常は <%= %> を使うのでエスケープし忘れがなくなり安全性が高まります。 また <%== %> は <%= %> より長いため、 間違えて <%== %> のほうを使う可能性は低いです (エスケープありよりエスケープなしのほうが書くのが面倒くさいことがポイントです)。
ホワイトリスト方式とは、すべてのデータはデフォルトで HTML エスケープして表示するようにし、エスケープしたくないデータだけ個別に明示するという方式です。 こうすることで、エスケープし忘れを防ごうというのが狙いです。
たとえば、次のようなデータを表示するとします。
ホワイトリスト方式では、まずこのデータをすべて HTML エスケープしたものを用意します。
そして、表示するときにはこの HTML エスケープしたデータ (@escaped_context) のほうを表示します。 ただし、テンプレート側で個別に明示すれば、エスケープしていないデータ (@context) のほうも表示できます。 こうすることで、エスケープし忘れを防ごうというわけです。
しかし筆者としては、以下のような理由からホワイトリスト方式には反対です。
筆者としては、ホワイトリスト方式を使うことで、テンプレートを書く人が HTML エスケープする・しないを気にすることなく、かつ必要な HTML エスケープが漏れなく行なわれるのであれば、ホワイトリスト方式に賛成しますが、現状はそうなっていません。 また前のセクションで説明した、デフォルトで HTML エスケープする方法と比べて、特に利点があるとも思えません。
もし、ホワイトリスト方式のよりよい利点がありましたら、ぜひ筆者に教えてください。
テンプレートシステムは、メインプログラムからテンプレートを読み込み、必要な箇所を書き換えて出力する仕組みです。 そのため、書き換える箇所を表す「目印」をテンプレート中に記述する必要があります。
テンプレートの HTML デザインを崩したくないなら、そこに埋め込む「目印」も HTML の仕様に含まれるものを利用すべきです。 たとえばタグやコメントや処理命令 (「<?php ?>」など) を使うことが考えられますが、最近はタグの属性を使うタイプが増えてきました。
目印として属性を使う場合、どのような属性を使うといいでしょうか。 まず任意の箇所を目印として使うためには、どのタグにでも使える必要があります。 またできれば、属性値に任意の文字列が書けるものがいいでしょう。
どのタグでも使えるような属性としては、次のものがあります。
XHTML の名前空間を使った独自属性は便利なのですが、HTML で使うことも考えると、おいそれと独自属性を使うわけにはいきません (テンプレートに対して HTML validator が使えなくなります)。 また共通属性のうち、テンプレートシステムでよく使われるのは id 属性や class 属性ですが、これらは属性値として使える文字が限られているため、たとえば「id=”if(items.length == 0)”」のような記述をすると HTML validator でエラーになります。
筆者のお勧めは title 属性です9。 title 属性だと、属性値として使える文字列に制限がありません。 また HTML テンプレートをブラウザで表示したときに、該当箇所にマウスカーソルを乗せれば属性値が表示されるというのも、テンプレートシステムに都合がいいです。
テンプレートシステムを自作しようとしている人がもしいるなら、title 属性を使うことを考えてみてください。
テンプレートシステムには、出力結果 (生成された Web ページ) をファイルやメモリにキャッシュする機能を持つものがあります。 しかし、これは設計上の誤りだと言えます。
キャッシュ機能を持つには、以下のような事項を考慮する必要があります。
しかし、こういったことはプレゼンテーション層で考慮すべきことなのでしょうか。 本来、プレゼンテーション層は「データをどう表示するか」という役目だけを果たせばよく、他の責務を果たす必要はないはずです。
キャッシュ機能が必要であれば、それはメインプログラム (または、MVC でいうところのコントローラ) が持つべきものであり、プレゼンテーション層が持つべきものではありません。 メインプログラムがキャッシュをコントロールすれば、たとえばデータベースへのアクセスを減らすという効果が期待できますが、プレゼンテーション層がキャッシュをコントロールするならこのような効果を期待することはできません。 出力結果のキャッシュ機能を有したテンプレートシステムというのは、プレゼンテーション層としての役割を間違えていると言えます。
なお、出力結果のキャッシュと、テンプレートシステムが内部で使用する構文木などのキャッシュとは、きちんと区別してください。 たとえば Jakarta Velocity はパースしたテンプレートの構文木をキャッシュできますが、これは出力結果のキャッシュとはわけが違うことに注意してください。 構文木をキャッシュすることはテンプレートシステムの役割に入りますが、出力結果のキャッシュはテンプレートシステムがする必要はありません。
本稿では、以下のような内容を説明しました。
次回からは、実際のテンプレートエンジンを紹介していきます。
厳密にいうと、出力形式は HTML に限りませんが、本稿は Web アプリケーションを対象としているため、主に HTML を出力することを前提とします。 ↩
これはテンプレートシステムから見た分け方というだけであり、他の分け方 (MVC など) を否定するものではありません。 ↩
厳密にいうと、テンプレートの HTML デザインが崩れるかどうかは単に記法の問題であり、プレゼンテーションロジックをテンプレート中に埋め込むかどうかは関係ありません。ただし、埋め込むタイプでデザインが崩れないような記法を採用しているのは少数派です。 ↩
Wicket は、実際にはフレームワークであり、テンプレートエンジンだけを取り出して使うことはできません。 ↩
ColdFusion や JSP のようにカスタムタグを使うものも考えられますが、それよりは独自属性を使う方がセンスがいいでしょう。 ↩
CGIKit と Tapestry は、実際には Web アプリケーションフレームワークであり、テンプレートエンジンとして使うことはできません。 ↩
デザイナーとプログラマーとが同じリポジトリを共有できる幸せな環境なら、この問題はあまり重要ではありません。デザイナーが Subversion や Git を使いこなせればの話ですが。 ↩
ただし、「複数の言語で使えるテンプレートエンジンを作りたい」のような、特別な事情がある場合は別です。 ↩
本音をいえば、特定の用途を定めないような共通属性が HTML の仕様にあると、テンプレートシステムにとっては大変都合がいいのですが。 ↩