発端はまぁ「JSん中にがりんごりんHTMLエレメントかかれてのHTML生成」を見て、色々とアレがナニだったりするあたりがきっかけなのですが。
「じゃぁどんな方法がよろしげ?」って考えて…まぁ、わりと定期的に一時期やっていた「テンプレートエンジン」っていう概念に対する再考察ネタとして、面白いかなぁと思ったので。
先に、おさらい。もっぱら「サーバサイド」でのお話。
元々、Perlなんかで組んでた2000年以前、くらいのころは、割と「プログラムん中にべた書き」が多かったと記憶しています。
ちなみに、おいちゃんが作っている「conv」というテンプレートエンジンの原型を作ったのが、1999年の、確か初夏ごろ。当時はC言語で実装していたのをありありと覚えております(笑
話を戻して…
まぁ、プログラム中に「ベタでエレメント書かれる」と、デザイン修正などが面倒なことこの上ない、ということを、体でというか工数で身につまされて。
でまぁ、世の中「業務ならテンプレートエンジン必須だよねぇ」って流れに流れていったんじゃなかろうか、と見ております。
…まぁどこぞの某Smartyとかで「テンプレートん中でgetパラメタ受け取ってpostパラメタ受け取ってDBハンドルもってSQL発行して関数切って」なんていうコードも散見されるので、なんていうか「…やれやれ」とか思いはするのですが。
おいといて。
本質的には、テンプレートエンジンって
・テンプレートがあって
・変数の塊りがあって
・テンプレートに変数の塊りをぶつけると、動的なHTMLが出来上がる
くらいのシンプルさが好みですし、基本はそーゆーもんだと思ってます。
なので、一端上述を前提に。
JSであろうとも、上述は結局代わりがないはずなので。
ってことは「元になるテンプレート」と「変数の塊り」が必要であろう、と。
で。
JSにおける「変数の塊り」は、おそらく「非同期通信(Ajax)で取得したjson」でよろしかんべ、と考えております。
この辺あんまり深い考察ではないので、突っ込みあったら大歓迎。
問題は「元になるテンプレート」をどこにおくかなんじゃなかろうか、と。
んで。なんとなく「JSのテンプレート展開」を、2つに切り分けて考えてみたりしました。
・部分的な展開
・HTML全部
後者のほうが多分イメージだけはしやすくて。すげぇ大雑把には「DOM構造全面改修」くらいの感じ(笑
…ただ、実際できるのかなぁ?
一つ考えてるのは
・cgi request(ページ本体)
・responseで、JSだけ(with 必要なら適当なパラメタ値)が書いてあるPageを受け取る
・JSを実行する
・・JSで、このページの元になる「HTML テンプレート」を取得する
・・JSで、「変数の塊り」を取得する
・・JSで「テンプレートに変数ぶつけて」動的なHTMLを作成する
・・JSで、動的なHTMLを「まるっと一通り」差し替える
こんな流れ。
…できなくもないけど、なんか1Pageあたり「JS用のPage」と「表示用のPage」があるのが面倒な気もするなぁ。
ん…
「BODYを空にしておいて、JSで作ってマルっとぶち込む」は普通にありだと思うのよ。
ただ、状況によっては「HEAD」のほうも置き換えたかったりするじゃない? そこを「ベタでゴリゴリ」書くんなら「いっそHTMLを全面的に」って思ったんだけど…乱暴かなぁ?
疑問に対して考察もせずに伏線はりっぱなしの疑問投げっぱなしジャーマンで、次w
「部分的な展開」。
ん…やっぱり勝手なイメージとしては。
・HTMLん中に「テンプレートとしてのDOM構造」を入れておく
・JSが動き出す
・・とりあえず「テンプレートとしてのDOM構造」を取得
・・動的なjsonを取得
・・テンプレートと変数の塊りから動的なHTMLを作成
・・適切な場所にぶち込む
こんな感じ。
ちなみにこれやるんなら「テンプレートとしてのDOM構造は、非表示とかにしないと一瞬きちゃないよ」って突っ込みをもらった。極めて正論だと思う。感謝。
このやりかただと…「複数個所」で若干「…面倒?」な可能性の気配が印象としてなんとなく感じたりはするんだけど(つまり考察も検証もしていない)、でもまぁ、その辺はなんか、妙手が生まれるような気もする。
あとは…テンプレートの実装?
色々考えたんだけど、結局「オートマトン組み上げてゴリゴリと文字列操作する」のが、もしかしたら一番早いのかしらん? 的な、やっぱり雑な発想(笑
で…調べてみると。
JSのテンプレートエンジン、やっぱり、それなりに出てるなぁ、と。
今度、すこし使い比べてみようかしらん?
例えば、の一例。 jTemplates ってのを見かけたです。
{#template MAIN} <div id="header">{$T.name}</div> <table> {#foreach $T.table as r} {#include row root=$T.r} {#/for} </table> {#/template MAIN} {#template row} <tr bgcolor="{#cycle values=['#AAAAEE','#CCCCFF']}"> <td>{$T.name.bold()}</td> <td>{$T.age}</td> <td>{$T.mail.link('mailto:'+$T.mail)}</td> </tr> {#/template row}
<select> <option{#if $T.optionCode}{#else} selected="selected"{#/if}>選択してね</option> {#param name=optionCode value=$T.optionCode} {#foreach $T.optionMap as option} <option value="{$T.option$key}"{#if $T.option$key == $P.optionCode} selected="selected"{#else}{#/if}>{$T.option}</option> {#/for} </select>
ふむ…なんとなく「とりあえずそんなに好みからはずれていない」っぽい雰囲気がする。
…そのうち、腰すえてやることになりそうなので、まずは一発目のメモってことで。