Kawa.netxp JKL.Hina - テンプレート展開クラス

JKL.Hina は JavaScript 用のテンプレート展開ライブラリです。
HTML ページ内に予め用意したテンプレートと、JSON なデータを与えて
テンプレート展開処理を高速に行います。
DOM を利用しているため、今のところ300行弱とソースも短いです。

Internet Explorer 6.0、 Firefox 1.0、Opera 8.0、Konquerer 3.3.2 で動作確認しています。
Safari 1.2 でも概ね動くようになりました。

ダウンロード

.tar.gz 版と .lzh 版の内容は同じです。(アーカイブ形式のみ違う)

 jkl-hina-0.18.tar.gz TAR-GZ

 jkl-hina-0.18.lzh LZH

更新履歴

2005/05/16 バージョン 0.01
最初のバージョン
2005/05/22 バージョン 0.10
属性値の変数置換の方法が変わりました。
属性名の先頭に _ をつけてください。 (例:style="〜"_style="〜"
2005/06/04 バージョン 0.15
onClick="〜" 等の JavaScript 中の変数置換にも対応しました。
onClick="alert('[/message]');" のように利用できます。
ただし、="〜" の中では this が使えませんので、ご注意ください。 (thanks to daisuke asano)
2005/06/17 バージョン 0.18
0.15のイベント処理(onClick="〜" 等)にはバグがあり、 ページ内に複数のイベントがあると正しく処理できていませんでした。m(..)m
修正したバージョンをリリースします。
また今回より、リリース前の動作確認を行うため、 テスト画面を設置しています。
[RUN ALL TEST]ボタンを押してください。(IE6は調子悪いかも?)
Konquerer 3.3.2 に対応しました。
Safari 1.2 に一部対応しました。(制限事項:属性処理が完全ではありません)

サンプル

[DEMO] ボタンを押すと、別ウインドウで実際の動作を確認できます。
各ページの [CLICK HERE]ボタンの上部がテンプレート部分です。
各サンプルは、ボタンを押すとテンプレート展開を行います。
展開結果はボタンの下部に表示されます。

なお、各リンク先のサンプル画面では 分かりやすいようにテンプレート部分も生で表示していますが、 通常の利用時は、テンプレートの外側を↓のように囲って非表示にしておきます。

<div style="display: none;">
    (中略。ここにテンプレート本体を入れる)
</div>

hello world

title と body の 2変数のみの単純な置換です。 DEMO

    var data = {
       title:   "hello world",
       body:    "Hina is yet another html template libraly for JavaScript."
    };

テンプレート:

<h1>[/title]</h1>
<p>[/body]</p>

list

制御構文 title="@foreach〜" を利用したループです。 DEMO

データ:

    var data = {
       list1:   [ 1, 2, 3 ]
    };

テンプレート:

<ul>
  <li title="@foreach i [/list1]">[/i]</li>
</ul>

table

こちらも制御構文 title="@foreach〜" を利用したループです。 DEMO
ループの値が連想配列になっています。

データ:

    var data = {
        table1: [
            { name: "Ruby",     author: "matz" },
            { name: "Perl",     author: "Larry Wall" },
            { name: "Python",   author: "Guido van Rossum" }
        ] 
    };

テンプレート:

<table border="1">
  <tr><th>name</th><th>author</th></tr>
  <tr title="@foreach line1 [/table1]">
	<td>[/line1/name]</td>
	<td>[/line1/author]</td>
  </tr>
</table>

conditional

ループと制御構文 title="@if〜" を利用した条件判定の組み合わせです。 DEMO
結果が真だった <div> 要素のみが表示されています。

テンプレート:

<div title="@foreach group1 [/groups]">
   <h1>[/group1/title]</h1>
   <div title="@if [/group1/no_data]">
      <em>This group has no data.</em>
   </div>
   <div title="@if [/group1/one_data]">
       This group has only one data: "[/group1/one_data/data]".
   </div>
   <div title="@if [/group1/many_data]">
       Here's the list of this group's data.
       <ul>
         <li title="@foreach item [/group1/many_data/list]">[/item]</li>
       </ul>
   </div>
</div>

JKL.Hina を呼び出す前に、JavaScript で前処理を行っているので、 データは省略。(ソースを見てください)

colors

属性値の書き換えです。 DEMO

データ:

    var data = {
        colors: [ "red", "green", "blue" ]
    };

テンプレート:

    <ul>
      <li title="@foreach c [/colors]" _style="color: [/c];">[/c]</li>
    </ul>

簡単な使い方

JKL.Hina を使う際には、以下の4要素をページ内に設置します。

1. ヘッダ内で jkl-hina.js を読み込む

head 要素内に1度だけ↓を記述します。

<script type="text/javascript" src="jkl-hina.js"></script>

JKLシリーズの他のライブラリは必要ありません。 jkl-hina.js は単品で動作します。
日本語は含まれないので、 charset="Shift_JIS" も不要です。

2. ページ内にテンプレートを記述する

テンプレート要素をページ内に用意しておきます。

<div id="src">
    <h1>[/title]</h1>
    <p>[/body]</p>
</div>

3. 展開先要素を用意する

テンプレート展開先となる要素は予め用意しておきます。
入れ物だけあれば、要素の中身は空でも構いません。
id 属性だけは指定してください。

<div id="dest"></div>

4. JavaScript で JKL.Hina を実行する

new コンストラクタの第1引数は、テンプレート要素のidを指定します。
expand メソッドの第1引数は、データを指定します。
expand メソッドの第2引数は、展開先要素のidを指定します。

var data = {
    title:   "hello world",
    body:    "Hina is yet another html template libraly for JavaScript."
};
var hina = new JKL.Hina( "src" );
hina.expand( data, "dest" );

expand メソッドを実行した時点で、展開先要素(dest)が置き換わります。

テンプレート要素と展開先要素は同じでも構いません。
ただし、その場合はテンプレートが上書きされてしまうため、
再度同じテンプレートを使って展開処理することができません。

処理仕様

大きく変数置換・条件判定・ループ・フィルタの4つの機能があります。

テキストノードの変数置換

テンプレート中の [/ と ] で囲まれた間に変数名を指定します。
JavaScript の変数の値に置換されて出力されます。

テンプレート:

これは[/key]です。

データ:

var data = {
    key:	"value"
};

展開結果:

これは、valueです。

変数置換処理の対象となるのは、タグで挟まれた間です。(テキストノード)
<tag>ここ</tag> が対象になります。
タグの内側 <ここ> には変数は利用できません。
属性値に変数を利用する場合は、 属性名の先頭に _ をつけてください

複数階層の変数置換

/ で階層構造(連想配列の子)を指定できます。

テンプレート:

これは、[/parent/child]階層です。
これは、[/aaa/bbb/ccc]階層です。

データ:

var data = {
    parent: {
        child:  2
    },
    aaa:    {
        bbb:    {
            ccc:    3
        }
    }
};

展開結果:

これは、2階層です。
これは、3階層です。

階層数(入れ子)の制限はありません。

属性値の変数置換

v0.10 から、属性値に変数を利用できるようになりました。
属性値に変数を利用したい場合は、属性名の先頭に _ をつけておきます。

テンプレート:

<a _href="[/url]">今すぐクリック</a>

データ:

var data = {
    url:	"http://www.kawa.net/"
};

展開結果:

<a href="//www.kawa.net/">今すぐクリック</a>

出力結果では、属性名の先頭の _ は外されています。

応用として、テンプレート処理用の _style="" と、 テンプレート状態の動作確認用の style="" を両方指定しておくことで、 動作確認にも利用できます。

※ XHTML/XML 的には勝手に属性を追加したくないところですが、 HTML 標準の属性値をブラウザ内部で string 型で保持できないため、 先頭に _ を付けた新しい属性名を導入しました。
未定義の属性名については、string 型で保持してくれるようです。
style⇒hina:style のように接頭辞 hina: を付ける案もありました(バージョンv0.10)が、 Opera では接頭辞に構わず属性を読んでしまうため、利用できませんでした。

_onClick="〜"などのイベント系属性も利用可能です。
ただし、変数 this は利用できません。また、return 文で返り値を戻すこともできません。
例えば、_onClick="return confirm(this);" は正しく動きません。
他の書き方で回避していただく必要があります。

制御構文 - 条件判定

データの内容による条件判定は、title="" 属性を利用します。
title 属性の本来の用途とは異なりますが、実際に title 属性を 利用していることは稀のため、現実的には問題がないと考えています。

<div title="@if [/bool]">
  真のときはここを表示する
</div>

data["bool"] の値が真の場合は、要素を出力します。
逆に、data["bool"] の値が偽の場合は、要素自体を削除します。
(divタグの内側でなく、div タグ自体がなくなります)

同様に、偽のときのみ出力、真なら削除する場合は @unless を使用します。

<div title="@unless [/bool]">
  偽のときはここを表示する
</div>

@if @unless はどちらも、要素内に子要素が入っていても構いません。(入れ子)
例えば、table 要素で条件判定すれば、テーブル全ての表示が ON/OFF されます。

制御構文 - ループ

リストやテーブルの行など、ループで表示を繰り返すには、 @foreach 制御構文を利用します。

テンプレート:

<ul>
<li title="@foreach loop [/list]">[/loop/name]</li>
</ul>

データ:

var data = {
    list: [
        { name: "Ruby" },
        { name: "Perl" },
        { name: "Python" }
    ]
};

展開結果:

<ul>
<li>Ruby</li>
<li>Perl</li>
<li>Python</li>
</ul>

このサンプルでは、data["list"] の配列の内容を順に data["loop"] に代入した上、
配列要素の和だけ <li> 要素が繰り返して出力されています。

フィルタ

変数置換では、“|”をつけてフィルタを利用できます。
変数の値をフィルタ処理した結果を出力します。
フィルタは“|”区切りで複数個並べることも可能です。

テンプレート:

これは[/key|uc]です。

データ:

var data = {
    key:	"value"
};

展開結果:

これは、VALUEです。

現在は、サンプルも兼ねて3つだけ組み込んでいます。

printf 相当のフィルタがあると便利なんですが。

TODO

コメントはこちらへ by AjaxCom

その他のページへのリンク

このページへのトラックバック by AjaxTB

トラックバックURL:http://www.kawa.net/service/tb/ajaxtb.cgi/works/js/jkl/hina.html

Kawa.netxp © Copyright 2005 Yusuke Kawasaki