JavaScriptでテンプレート

Ajaxでぐりぐりやっていると、どうしてもJavaScriptからhtmlを生成する場面が多くなります。一つ一つdocument.createElementして気が狂いそうになったり、script.aculo.usのBuildler.nodeでDOM構築してみたはいいけど、面倒な部分をinnerHTMLで書いたらhtmlがエスケープされてもにょった、なんてことになりがちです。このままだと開発効率も保守性もひどいことになってしまいます。IEJavaScriptがうまく動かなくて何とか修正した、と思ったらCSSのバグにブチ当たってDOM構成変更、なんてことをやっていると動いた頃には二度と見返したくないソースの出来上がり。JavaScriptコーディングとCSSの分業なんて夢のまた夢です。

そんな状況を打破するためにJemplateJSmartyといったJavaScriptのテンプレートエンジンが登場し始めています。とは言え、そこまで本格的なものでなくてもいいかな、ということでこんなものを書いてみました。

JVars = function(){}
JVars.prototype = {
    template_vars: [],

    assign: function(key, value) { this.template_vars[key] = value; },

    fetch: function(filename)
    {
        var tpl = ajax.gets(filename).replace(/\n/g, '');
        var tpl = tpl.replace(/{\$([\w\.\[\]]+)}/g, function(str, p1, p2) { return "'+this.template_vars."+p1+"+'"; });
        var tpl = "'"+tpl+"'";
        eval('var content='+tpl);
        return content;
    }
}

これを、jvars.jsとして保存します。ライブラリとしてminiAjaxを使用しますので、リンク先に掲載されているスクリプトをminiajax.jsとして同じディレクトリに入れます。次に、テンプレートを用意します。

<p>{$key}:{$value}</p>
<p>{$param[0]} and {$param[1]}</p>
<p>{$hash.one} {$hash.two}</p>

こんな感じにしてみました。これをtest.tplとして保存します。そして、こいつらを呼び出すHTMLがこんな感じ。

<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>JVars</title>
  <script type="text/javascript" src="miniajax.js"></script>
  <script type="text/javascript" src="jvars.js"></script>
  <script type="text/javascript">
//<![CDATA[
window.onload = function() {
    var jv = new JVars();
    jv.assign('key', 'きー');
    jv.assign('value', 'あたい');
    jv.assign('param', ['apple', 'banana']);
    jv.assign('hash', {"one":"わん", "two":"つー"});
    $('result').innerHTML = jv.fetch('test.tpl');
}
//]]>
  </script>
 </head>
 <body>
  <div id="result" style="border:1px solid #666"></div>
 </body>
</html>

変数をassignして、テンプレートをfetchする。Smartyライクな呼び出し方でテンプレートが機能します。実際に動かすとこんな感じになります。

変数置換以外は何もできないし、デリミタも変更できない低機能なものですが、ちょっとした処理には手頃かも。もう少し育ててみるか?