Tempura - リファレンスマニュアル

テンプレートの書式

Tempuraのテンプレートは、REXMLでパース可能なXML形式のテキストとして表 現します。テンプレートは、REXML::Document.newに第一引数としてそ のまま渡されます。いくつかのXML属性とその値がTempuraの処理に利用されま す。

XML属性

以上のXML属性がTempuraによる展開の結果に影響を与えます。これらのXML属 性自身は、Tempuraによる展開の出力結果からは削除されます。

以降、各XML属性の仕様を説明します。

_nil_

この属性を持つXML要素をまるごと削除します。XMLの仕様上、属性値を省略 することはできませんが、値は無視されます。 XHTMLをプレビューするとき などに、ダミーのXML要素を置くのに使うことができます。

例 (展開前):

<ul>
  <li>天丼</li>
  <li>天ざる</li>
  <li _nil_="">(すきやき)</li>
</ul>

例 (展開後):

<ul>
  <li>天丼</li>
  <li>天ざる</li>
</ul>
_child_

この属性を持つXML要素の内容を、属性値を評価した結果で置き換えます。 属性値は、Rubyスクリプトとして実行時に指定された環境(binding)で評価 されます。ただし例外として、_block_属性の影響下にあるときには、 ブロックの環境で評価されます。

_self_がXML要素自体をまるごと置き換えるのに対して、_child_では、 XML要素の内容を置き換えます。

評価の結果が:

例 (展開前):

<p _child_="Time.now">current time</p>

例 (展開後):

<p>Wed Sep 17 17:47:35 JST 2003</p>
_self_

この属性を持つXML要素自体を、属性値を評価した結果で置き換えます。属 性値は、実行時に指定された環境(binding)でRubyスクリプトとして評価さ れます。ただし例外として、_block_属性の影響下にあるときには、 ブロックの環境で評価されます。

_child_がXML要素自体ではなく内容を変更するのに対して、_self_で は、XML要素自体を置き換えます。

評価の結果が:

例 (展開前):

<p _self_="Time.now">current time</p>

例 (展開後):

Wed Sep 17 17:47:35 JST 2003
_child_xml_, _self_xml_

それぞれ_child_、_self_と基本的には同じです。しかし、評価の結果が、 nil・false・REXML::Childのインスタンスのいずれでもないとき(その他の オブジェクトの場合)の振舞いが異なります。

ここまでは、それぞれ_child_、_self_と同じですが

となります。

_child_と_self_では、文字列に変換した評価結果がXML形式であろうがなか ろうが、まるごとテキスト要素として扱われます。

それに対して、_ child_xml_と_self_xml_では、文字列に変換した評価結果 をREXMLで一度パースします。したがってXML形式の文字列はREXML::Childの インスタンスとして扱われることになります。

この_xml_という接尾辞がつくXML属性は、評価結果がXML形式の文字列を返 すことが想定される場合、それを文字列でなくXML部品として扱いたいとき に使います。具体的には、XMLで書かれたTempura::Divテンプレートの中に、 Div標準のErbで書かれたDiv::Divテンプレートを埋め込むときなどに使います。

以下に、 @erbdiv.to_div(context)を評価した結果が "<div>hello</div>" という文字列を返す場合の、_xml_接尾辞の有無 による結果の違いを例示します。

この結果から、ErbによるDiv::Divを埋め込む場合には、 _child_xml_や_self_xml_の方が役に立つだろうことが推測できるでしょうか。

_attr_* (名前が_attr_で始まるXML属性)

この属性を持つXML要素の指定された属性を、属性値を評価した結果を文字 列化したもので、置き換えます。_attr_*属性名の_attr_ を取り除いたもの が変更される属性(ターゲット属性)の名前になります。

属性値は、実行時に指定された環境(binding)でRubyスクリプトとして評価 されます。ただし例外として、_block_属性の影響下にあるときには、 ブロックの環境で評価されます。評価の結果により、以下のようにターゲッ ト属性を変更します。

例 (展開前):

<p _attr_time="Time.now">hello world</p>

<option _attr_selected="nil" selected="true"/>
<option _attr_selected="false" selected="true"/>
<option _attr_selected="%(false)" selected=="true"/>
<option _attr_selected="true"/>
<option _attr_selected="%(true)"/>

例 (展開後):

<p time="Wed Sep 17 17:47:35 JST 2003">hello world</p>

<option/>
<option selected="true"/>
<option selected=="false"/>
<option selected="true"/>
<option selected="true"/>
_block_

この属性を持つXML要素を、特定書式の属性値の内容にしたがって、複製し ます。属性値はつぎの書式で記述します。

_block_属性値 := Rubyスクリプト片 '//' ブロックメソッド名 '//' ブロック引数リスト

Rubyスクリプト片の評価結果に対して、ブロックメソッドが呼ばれます。ブ ロックが呼ばれた回数だけXML要素が複製されます。複製されたXML要素は、 ブロックの環境(binding)でTempura展開されます。

例1 (展開前):

<li _block_="1..3//each//i" _child_="i">(will be replaced)</li>

例1 (展開後):

<li>1</li><li>2</li><li>3</li>

例2 (展開前):

<tr _block_="{:aaa=>111,:bbb=>222,:ccc=>333}//each//key,val">
  <td class="key" _child_="key">(key)</td>
  <td class="val" _child_="val">(val)</td>
</tr>

例1 (展開後):

<tr>
  <td class="key">aaa</td>
  <td class="val">111</td>
</tr><tr>
  <td class="key">bbb</td>
  <td class="val">222</td>
</tr><tr>
  <td class="key">ccc</td>
  <td class="val">333</td>
</tr>
_event_

この属性を持つXML要素の名前が"a"または"form"の場合に、その要素をユー ザのWEBアプリケーションに対する操作として扱い、特定書式の属性値の内 容にしたがって変更します。その他の要素の場合には何もしません。属性値 はつぎの書式で指定します。

_event_属性値 := イベント名 [ パラメータ ]*
パラメータ    := '//' キー '==>' 値

例1 - form要素 (展開前):

<form method="POST" _event_="add">
  name: <input type="text" name="name"/>
  age : <input type="text" name="age"/>
  <input type="submit" value="add"/>
</form>

例1 -form要素 (展開後):

<form method="POST" action="myapp.cgi"><input type="hidden" name="event" value="hello"/>
  item : <input type="text" name="item"/>
  price: <input type="text" name="price"/>
  <input type="submit" value="add"/>
</form>

例2 - a要素 (展開前):

<a href="dummy" _event_="add//item==>%(tenzaru)//price==>9//time==>Time.now.to_i">add tenzaru</a>

例2 -a要素 (展開後):

<a href="myapp.cgi?event=add;item=tenzaru;price=9;time=1064208436">add tenzaru</a>

例3 - Div (展開前):

<form method="POST" _event_="add">
  name: <input type="text" name="name"/>
  age : <input type="text" name="age"/>
  <input type="submit" value="add"/>
</form>

例3 -Div (展開後):

<form method="POST" action="/div">
    <input name='div_id' type='hidden' value='123456789'/>
    <input name='div_cmd' type='hidden' value='add'/>
  item : <input type="text" name="item"/>
  price: <input type="text" name="price"/>
  <input type="submit" value="add"/>
</form>
_action_

この属性は、_event_属性と組み合わせて使うためのもので、aおよび form要素のイベントの送信先を変更します。

この属性を持つXML要素が、"a"または"form"という名前で、かつ _event_属性を持っている場合に、_event_によって展開される action名が、この属性の値に置き換えられます。テンプレート展開後のform 要素のaction属性、もしくはa要素のhref属性の値に影響します。この属性 による置き換えは、最優先されます。

例1 - form要素 (展開前):

<form method="POST" _event_="hello" action="dummy.cgi" _action_="alt.cgi">
</form>

例1 -form要素 (展開後):

<form method="POST" action="alt.cgi"><input type="hidden" name="event" value="hello"/>
</form>

例2 - a要素 (展開前):

<a href="dummy.cgi" _action_="alt.cgi" _event_="hello">hello</a>

例2 -a要素 (展開後):

<a href="alt.cgi?event=hello">hello</a>

文字コード変換器

Tempuraテンプレートにはそれぞれ文字コード変換器を指定することができま す。Tempura内部では、文字コードをUTF-8で扱います。UTF-8以外の文字コー ドで記述されたテンプレートを使うためには、その文字コードとUTF-8を相互 に変換するための文字コード変換器を指定する必要があります。

文字コード変換器は、つぎの2つのインスタンスメソッドを備えた任意のオブ ジェクトです。

文字コード変換器#to_u8(str)

文字列をUTF-8文字列に変換して返す。

文字コード変換器#from_u8(str)

UTF-8文字列を8文字列に変換して返す。

あらかじめ以下の文字コード変換器が定義されています。

Tempura::CharConvDefault

何もしない変換器。デフォルト。

Tempura::CharConvEUC

EUC-JPのための変換器。

Tempura::CharConvSJIS

ShiftJISのための変換器。

クラス

Tempura::Templateクラス

複数のTempuraテンプレートと1つのTempura展開器を包むオブジェクトを定義 するクラスです。選択されたテンプレートを引数として与えられたデータで展 開する機能を持っています。Tempuraを典型的なテンプレートライブラリとし て使う場合、通常はこのクラスのインスタンスを生成して使います。

このクラスのインスタンスは、デフォルトテンプレートを含む複数のテンプレー トを持つことができます。各テンプレートは特定のキーオブジェクトと関連づ けられます。展開時に、与えられたキーに関連づけられたテンプレートが見つ からない場合は、デフォルトテンプレートが使用されます。

各テンプレートはそれぞれ関連する文字コード変換器を持つことができます。

ロード:

require 'tempura/template'

クラスメソッド:

Tempura::Template.new([path, charconv, safe_level])

Tempura::Templateオブジェクトを生成します。pathには、デフォ ルトテンプレートを記述したファイルへのパスを指定します。 charconvには文字コード変換器を指定します。 safe_levelはテンプレートを展開するときの$SAFEの値を指定しま す。

Tempura::Template.new_with_string(str[, charconv, safe_level])

Tempura::Templateオブジェクトを生成します。strには、デフォル トテンプレートを記述した文字列を指定します。charconvには 文字コード変換器を指定します。safe_levelはテンプレート を展開するときの$SAFEの値を指定します。

メソッド:

Tempura::Template#default_action

_event_属性を展開するときにaction属性の値とする文字列を返します。 デフォルトは空文字列""です。この値は、テンプレート展開後のform要素 のaction属性、もしくはa要素のhref属性の値に、影響します。

Tempura::Template#default_action=(str)

_event_属性を展開するときに、action属性の値とする文字列を設定しま す。この値は、テンプレート展開後のform要素のaction属性、もしくはa 要素のhref属性の値に、影響します。

default_action = "myapp.cgi" のとき

<form  method="POST" _event_="hello">
...
</form>
<a href="dummy" _event_="hello">hello</a>

の展開結果は

<form method="POST" action="myapp.cgi"><input type="hidden" name="event" value="hello"/>
...
</form>
<a href="myapp.cgi?event=hello">hello</a>

となります。

Tempura::Template#default_event_key

_event_属性を展開するときに、eventを表すキー文字列として展開する文 字列を返します。デフォルトは"event"です。

Tempura::Template#default_event_key=(val)

_event_属性を展開するときに、eventを表すキー文字列として展開する文 字列を設定します。

default_event_key = "mycmd" のとき

<form  method="POST" _event_="hello">
...
</form>
<a href="dummy" _event_="hello">hello</a>

の展開結果は

<form method="POST" action=""><input type="hidden" name="mycmd" value="hello"/>
...
</form>
<a href="?mycmd=hello">hello</a>

となります。

Tempura::Template#set(path[, key, charconv])

pathで指定されたファイルの内容を、keyと関連づけられた テンプレートとして設定します。keyが省略された場合はデフォル トテンプレートとなります。charconvには文字コード変換器 を指定します。

Tempura::Template#set_with_string(str[, key, charconv])

strで指定された文字列を、keyと関連づけられたテンプレー トとして設定します。keyが省略された場合はデフォルトテンプレー トとなります。charconvには文字コード変換器を指定します。

Tempura::Template#expand(model[, key])

modelと関連付けられた環境(binding)で、keyと関連付けら れたテンプレートを展開し、結果を文字列として返します。keyが 省略された場合はデフォルトテンプレートを展開します。

model

Bindingインスタンスの場合

テンプレートはその環境(binding)で評価されます

その他のインスタンスの場合

テンプレートはインスタンスの環境(binding)で評価されます

Tempura::Template#expand_to_document(model[, key])

modelと関連付けられた環境(binding)で、keyと関連付けら れたテンプレートを展開し、結果をREXML::Documentインスタンスとして 返します。keyが省略された場合はデフォルトテンプレートを展開 します。

Tempura::Divクラス

テンプレートにTempuraテンプレートを使うDiv::Divの派生クラスです。Divに ついては Divのウェブサイト などを参照してください。

スーパークラス:

Div::Div

ロード:

require 'tempura/div'

クラスメソッド:

Tempura::Div.new(session)

Tempura::Divオブジェクトを生成します。

Tempura::Div.set_template(path[, key, charconv])

pathで指定されたファイルの内容を、keyと関連づけられた テンプレートとして設定します。keyが省略された場合はデフォル トテンプレートとなります。charconvには文字コード変換器 を指定します。

Tempura::Div.set_safe_level(safe_level)

テンプレートを展開するときの$SAFEの値を指定します。

Tempura::Div.reload_template

テンプレートをファイルから再読み込みします。

メソッド:

Tempura::Div#select_template(key)

与えられたキーと関連付けられたテンプレートをデフォルトテンプレート にします。

Tempura::Div#to_html_document([context, key])

レシーバインスタンスの環境(binding)で、keyと関連付けられたテ ンプレートを展開し、結果をREXML::Documentインスタンスとして返しま す。keyが省略された場合はデフォルトテンプレートを展開します。 Erbで書かれたDivテンプレートの中から呼ぶ場合は、このメソッドでなく、 文字列を返すバージョンのTempura::Div#to_htmlを呼ぶべきです。

Tempura::Div#to_html([context, key])

レシーバインスタンスの環境(binding)で、keyと関連付けられたテ ンプレートを展開し、結果を文字列として返します。keyが省略さ れた場合はデフォルトテンプレートを展開します。Tempuraテンプレート で書かれたDivテンプレートの中から呼ぶ場合は、このメソッドでなく、 REXML::Documentインスタンスを返すバージョンの Tempura::Div#to_html_document を呼ぶ方が効率的です。

Tempura::Div#to_div_document([context, key])
Tempura::Div#to_div([context, key])

Tempura::Expanderクラス

Tempuraテンプレート展開器を定義するクラスです。このクラスが、Tempuraの 核心部といえます。とくにカスタマイズなどをする必要がなければ、通常はこ のクラスを直接扱う必要はありません。

ロード:

require 'tempura/expander'

クラスメソッド:

Tempura::Expander.pre_expand(rexml_element[, bang_p])
Tempura::Expander.new([safe_level])

メソッド:

Tempura::Expander#safe_level
Tempura::Expander#pre_expand(rexml_element[, bang_p])
Tempura::Expander#expand(context, rexml_element, charconv[, bang_p])
Tempura::Expander#expand_to_string(context, rexml_element, charconv[, bang_p])
Tempura::Expander#default_action
Tempura::Expander#default_action=(action)
Tempura::Expander#default_event_key
Tempura::Expander#default_event_key=(event_key)
Tempura::Expander#param_filter(&proc)
Tempura::Expander#action_filter(&proc)

Tempura::SourceContainerクラス

Tempuraテンプレートソース(Tempura::Sourceインスタンス)のコンテナを定義 するクラスです。各テンプレートはキーオブジェクトと関連付けられて管理さ れます。通常はこのクラスを直接扱う必要はありません。

ロード:

require 'tempura/source_container'

クラスメソッド:

Tempura::SourceContainer.new

メソッド:

Tempura::SourceContainer#[key]
Tempura::SourceContainer#[key] = val
Tempura::SourceContainer#default
Tempura::SourceContainer#default=(val)
Tempura::SourceContainer#set(key, path[, charconv])
Tempura::SourceContainer#set_as_string(key, string[, charconv])
Tempura::SourceContainer#reload

Tempura::Sourceクラス

REXML::Documentインスタンスと関連する文字コード変換器を包むオブジェク トを表現するクラスです。通常はこのクラスを直接扱う必要はありません。

ロード:

require 'tempura/source'

クラスメソッド:

Tempura::Source.new_with_string(str[, charconv])
Tempura::Source.new(path[, charconv])

メソッド:

Tempura::Source#path
Tempura::Source#charconv
Tempura::Source#name
Tempura::Source#name=(val)
Tempura::Source#reload
Tempura::Source#fetch_document