jTemplatesのMultiTemplatesが思ったのと違う件 

はてなブックマーク - jTemplatesのMultiTemplatesが思ったのと違う件
Bookmark this on Delicious

最近javascriptをさわり始めておりまして、そうすると動的にデータを操作するのでjTemplatesというテンプレートエンジンを使う事にしました。jQueryのプラグインだという事と、1つのファイルで複数のテンプレートを定義出来るという事で選んだわけですが、「複数テンプレート」のニュアンスがちょっと思ってたのと違うのでメモ書きです。

サーバーサイドのテンプレートエンジンはページ単位が多いわけですが、javascriptで動的に入れ替えたいのはページ単位というよりは、HTMLのブロック要素単位だと思います。なのでページ単位で作ったテンプレートファイルの中にブロック用のテンプレートを複数持たせたいのです。

まずjTemplatesの基本的な使い方は以下のような感じで、テンプレートを特定のブロックにセットして、データと一緒にprocessTemplateを走らせるという流れになります。

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script type="text/javascript" src="jquery-1.3.2.js"></script>
    <script type="text/javascript" src="jquery-jtemplates.js"></script>
    <script type="text/javascript">
    $(function() {
       var data = {
        teams: [
            { name:"巨人", win:50, lose:28 },
            { name:"中日", win:51, lose:34 },
            { name:"広島", win:35, lose:46 },
        ]
      };
      $("#result").setTemplateURL("test.tpl");
      $("#result").processTemplate(data);
    })
    </script>
  </meta></head>
  <body>
    <div id="result"></div>
  </body>
</html>
test.tpl (テンプレートファイル)
{#template MAIN}
<table>
  {#foreach $T.teams as team}
  <tr>
     <td> {$T.team.name} </td>
     <td> {$T.team.win}  </td>
     <td> {$T.team.lose} </td>
  </tr>
  {#/for}
</table>
{#/template MAIN}

続いて複数のテンプレートを定義します。テーブルの代わりにリストにしてみました。

{#template MAIN}
<table>
  {#foreach $T.teams as team}
  <tr>
     <td> {$T.team.name} </td>
     <td> {$T.team.win}  </td>
     <td> {$T.team.lose} </td>
  </tr>
  {#/for}
</table>
{#/template MAIN}
 
{#template SUB}
<ul>
  {#foreach $T.teams as team}
  <li>
     {$T.team.name} : {$T.team.win} : {$T.team.lose}
  </li>
  {#/for}
</ul>
{#/template SUB}

ここで問題なのは新しく定義したSUBテンプレートを指定してロードする方法が無い事です。そんなバカなと思ってソースを見てみるとMAINというテンプレートを即値で読み込む作りになっています。
じゃあ他のテンプレートは何に使うのかというと、どうもテンプレート内で部品化できる部分をテンプレートとして定義して、それをincludeする事で余分な繰り返し等を避けれるって言う話のようです。

このままでは悔しいので、適当に変数を利用してMAIN内で分岐させれば良いかもと思ったのですが、{#include}内で変数を展開する事が出来ないようです。

以下のように外部変数を元に分岐させられない
{#template MAIN}
  {#include $P.name root=$T}
{#/template}

というわけで結局一つのテンプレートファイルで、実質的に複数のテンプレートを使おうとすると、外部変数と{#if}で無理矢理分岐させる事になりそうです。

// MAINの中で無理矢理分岐させる
{#template MAIN}
  {#if $P.name == "SUB1"}
    {#include SUB1 root=$T}
  {#elseif $P.name == "SUB2"}
    {#include SUB2 root=$T}
  {#/if}
{#/template MAIN}
 
{#template SUB1}
<h1>{$P.name}</h1>
<font color="#0000FF">{$T.param}</font>
{#/template SUB1}
 
{#template SUB2}
<h1>{$P.name}</h1>
<font color="#FF0000">{$T.param}</font>
{#/template SUB2}

一見、テンプレートファイルが増えるよりも、まだ保守性が良さそうですが、分岐部分の修正によって既存部分にまで影響する可能性もあり微妙です。

もっといい方法がありそうですね。見つけたらまた書きたいと思います。

参考

  • http://blog.livedoor.jp/techblog/archives/64748832.html
  • http://jtemplates.tpython.com/

関連する記事

タグ: , ,

コメントをどうぞ