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 版の内容は同じです。(アーカイブ形式のみ違う)
[DEMO] ボタンを押すと、別ウインドウで実際の動作を確認できます。
各ページの [CLICK HERE]ボタンの上部がテンプレート部分です。
各サンプルは、ボタンを押すとテンプレート展開を行います。
展開結果はボタンの下部に表示されます。
なお、各リンク先のサンプル画面では
分かりやすいようにテンプレート部分も生で表示していますが、
通常の利用時は、テンプレートの外側を↓のように囲って非表示にしておきます。
<div style="display: none;"> (中略。ここにテンプレート本体を入れる) </div>
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>
制御構文 title="@foreach〜" を利用したループです。
DEMO
データ:
var data = { list1: [ 1, 2, 3 ] };
テンプレート:
<ul> <li title="@foreach i [/list1]">[/i]</li> </ul>
こちらも制御構文 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>
ループと制御構文 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 で前処理を行っているので、 データは省略。(ソースを見てください)
属性値の書き換えです。 DEMO
データ:
var data = { colors: [ "red", "green", "blue" ] };
テンプレート:
<ul> <li title="@foreach c [/colors]" _style="color: [/c];">[/c]</li> </ul>
JKL.Hina を使う際には、以下の4要素をページ内に設置します。
head 要素内に1度だけ↓を記述します。
<script type="text/javascript" src="jkl-hina.js"></script>
JKLシリーズの他のライブラリは必要ありません。
jkl-hina.js は単品で動作します。
日本語は含まれないので、 charset="Shift_JIS" も不要です。
テンプレート要素をページ内に用意しておきます。
<div id="src"> <h1>[/title]</h1> <p>[/body]</p> </div>
テンプレート展開先となる要素は予め用意しておきます。
入れ物だけあれば、要素の中身は空でも構いません。
id 属性だけは指定してください。
<div id="dest"></div>
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 相当のフィルタがあると便利なんですが。
トラックバックURL:http://www.kawa.net/service/tb/ajaxtb.cgi/works/js/jkl/hina.html
Kawa.netxp © Copyright 2005 Yusuke Kawasaki