2013.04.27
ウェブ開発におけるテンプレート言語の限界
サーバ側でHTMLを生成する、いわゆる「動的」なウェブサイトの開発では、たいてい「テンプレート言語」を用いる。プログラム中でHTMLを直接書き出してしまうのではなく、HTMLのテンプレートは別ファイルにしておく、という方法だ。プログラムでは、そのテンプレートファイルを読み込んで、テンプレート中にある変数に値を埋め込んでいく、というふうにする。

このとき、HTMLのテンプレートには、変数やループ構造、条件文などが必要になる。こういったものを記述するのに使うのが「テンプレート言語」である(それを解釈するソフトウェアが「テンプレートエンジン」)。例えば、先日紹介した「Jinja2」は、Pythonのテンプレート言語(テンプレートエンジン)でもっとも有名なもののひとつである(Jinja2による記述の実例は、ウィキペディアの解説ページを参照)。

なぜ、プログラム中でHTMLを直接書き出すのではなく、わざわざテンプレートファイルに切り出して、テンプレート言語を使ったりするのか。それは、システムのメンテナンスをやりやすくするためである。もし、プログラム中でHTMLを直接書き出していると、HTMLが少し変わった場合にも、プログラムを変更する必要が生じる。しかし、HTML部分をテンプレートに切り出しておけば、HTMLが変わった場合、プログラムをいじる必要がなく、テンプレートの変更だけで済む。また、テンプレートはおおむねHTMLのような外観をしているので、パッと見てHTMLの構造がわかりやすい、というメリットもある。いっぽうプログラムの側も、HTMLを直接書き出すと、コードがわりと汚くなりがちだ。テンプレートを使ったほうが、一般にコードもきれいになりやすいだろう。

しかし、このテンプレートを使うアプローチにも限界がある。あるていど複雑なサイトの場合、似たようなパターンがたびたび出てくるものの、それらの挙動や表示がちょっとずつ違う、ということがよくある。こういう場合は、テンプレートを使わず、むしろ完全にプログラムの中でHTMLを生成したほうがいい、ということも少なくない。

私の場合、プログラミング言語はPythonを使い、テンプレート言語はJinja2を使うことが多い。Jinja2はとてもよくできているし、スピードも十分なのだが、やはりテンプレート言語にすぎないので、Pythonの表現力にはかなわない。やりたいことが複雑になってくると、テンプレートがJinja2の記述だらけになってきて、むしろそれを維持するのが困難になる、ということがよくある。こういうとき、私は無理にテンプレートを使わず、Pythonのクラスや関数だけを組み合わせて、実現したいHTMLを生成するようにしている。

プログラム中でHTMLを書き出すのではなく、HTMLはテンプレートに切り出す、というのが基本であり、原則ではある。しかし、あるていど複雑になってくると、この原則が通用しないこともあるのだ。

先日の「1ファイルに全部詰め込む方式は、思いのほか効率がいい」というのも、ある意味ではこの話に近い。「1ファイルに全部詰め込む」という構成は、まともなアプローチとは言えず、いわば「邪道」である。しかし、現実に開発スピードが早く、生産性が高いのは、1ファイル方式のほうかもしれないのだ。

「DRY」はつねに正しいわけではない 重複と密結合のトレードオフ」というのも、これと似た話である。基本や原則は重要だが、それを破ったほうがうまくいく、という場合も存在するのだ。


関連エントリ:
1ファイルに全部詰め込む方式は、思いのほか効率がいい
http://mojix.org/2013/04/23/one-file-strategy
「神社(Jinja)」という名前のソフトウェア
http://mojix.org/2013/04/12/jinja-software
「DRY」はつねに正しいわけではない 重複と密結合のトレードオフ
http://mojix.org/2013/01/10/dry-duplication-coupling