hideden.hatenablog.com

はてなぶろぐー。URLなげー。

jTemplatesのforeachの中から元の$Tを参照する方法

jQuery+jTemplatesでごにょごにょやってて、ちょっと悩んだのでメモ。


データ

var data = {
    status: 'success',
    base_url: 'http://localhost/entry/edit/',
    entries: [
        {
            id: "1",
            title: "title1"
        },
        {
            id: "2",
            title: "title2"
        }
    ]
};

テンプレート

{#if status == 'success'}
<ul>
  {#foreach $T.entries as entry}
    <li><a href="{$T.base_url}{$T.entry.entry_id}">{$T.entry.title}</a></li>
  {#else}
    <li>no entries.</li>
  {#/foreach}
</ul>
{#else}
failed to load.
{#/if}

これ素直に動きそうだけど動かない。{#foreach}の外での$Tと{#foreach}の中での$Tがどうやら別物のよう。{#foreach}内では"$T.entries as entry"で指定した$T.entryしか見えないので{$T.base_url}が空白になる。

マニュアルを一通り見たけどそれらしい解説もないのでググってみると

http://www.memorycraft.jp/2008/11/jtemplatesforeach.html

という記事を発見。確かに{#param name=org value=$T}とか書いておくと{$P.org.base_url}で参照できるっぽいのだが、なんだか気持ち悪い。

jTemplate 0.7.5のソースをざっと眺めてみたところ、{#foreach}に渡すoptionとしてextDataなるものがあるのを発見。

以下のような感じで

{#if status == 'success'}
<ul>
  {#foreach $T.entries as entry extData=$T}
    <li><a href="{$T.base_url}{$T.entry.entry_id}">{$T.entry.title}</a></li>
  {#else}
    <li>no entries.</li>
  {#/foreach}
</ul>
{#else}
failed to load.
{#/if}

"{#foreach $T.entries as entry extData=$T}" という感じでextData optionに$Tを渡しておくと、うまい具合に{$T.base_url}も取れるようになった。



・・・使い方として正しいのかどうかは不明。


extDataはjTemplates 0.7以上で実装された{#for}を内部的に{#foreach}構文に変換するopFORFactoryで使ってるだけのようで、

var extData = (this._option.extData !== undefined) ? (eval(this._option.extData)) : {};

と普段は使われてないような気がする。とりあえず特に弊害はなさそうだと勝手に判断する事にした。