Kwartzリファレンスマニュアル
last update: $Date: 2005-03-07 08:15:41 +0900 (Mon, 07 Mar 2005) $
はじめに
このドキュメントは、Kwartzのリファレンスマニュアルです。 プレゼンテーション用言語「PL」、ディレクティブ、コマンドラインオプション、 設定オプションについて説明しています。
目次
プレゼンテーション用言語「PL」
PLとは、Kwartzにおいてプレゼンテーションロジックを記述するのに利用される言語です。 この章では、PLの書き方について説明します。
コメント
「//」から改行まではコメントになります。
// ここはコメント
文字列
文字列は「"..."」または「'...'」で表します。
前者には改行(Line Feed)「\n」と復改(Carriage Returen)「\r」とタブ(Tab)「\t」を含めることができます。
'foo bar' // 文字列 "foo bar\n" // 改行を含む文字列
真偽値、null
式の中で true、false、null が使えます。
flag = obj == null ? true : false;
true、false、nullは各言語において次のように変換されます。
| 変換先言語 | true | false | null |
|---|---|---|---|
| PHP | TRUE | FALSE | NULL |
| eRuby | true | false | nil |
| JSP(JSTL) | true | false | null |
変数
変数はアルファべットまたは「_」で始まり、アルファベットと数字と「_」が連続したものです。
また変数には型がなく、変数宣言もする必要がありません(*1)。
- (*1)
- この性質から、PLまたはPL-Kwartzで書かれたプログラムを、変数に型のある言語や変数宣言が必要な言語に変換するのは困難です。
演算子
演算子には次のものが使用できます。基本的には、文字列用と数値用とで演算子を分けてはいません(*2)。
| 比較演算子 | == != < <= > >= |
| 論理演算子 | && || ! |
| 算術演算子 | + - * / % |
| 文字列の連結 | .+ |
| 条件演算子 | ?: |
文字列の連結演算子「.+」は、eRubyでは「+」に、PHPでは「.」に、
JSTL1.1では関数fn:join()に変換されます。
JSTL1.0では連結演算子がないので、トリッキーな方法で凌いでいます。
PLプログラム(PL):
filename = basename .+ '.plogic';
出力用スクリプト:
### for eRuby
<% filename = basename + ".plogic" %>
### for PHP
<?php $filename = $basename . ".plogic"; ?>
### for JSTL 1.1
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="filename" value="${fn:join(basename,'.plogic')}"/>
### for JSTL 1.0
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<c:set var="filename" value="${basename}${'.plogic'}"/>
条件演算子(3項演算子)はeRubyとPHPとJSTL1.1では使用できますが、JSTL1.0では使用できません。 そのため条件演算子を含む式は、JSTL1.0ではif文(に相当する<c:choose>)に変換されます。
PLプログラム(PL):
color = ctr % 2 == 0 ? '#FFCCCC' : '#CCCCFF';
出力用スクリプト:
### for eRuby
<% color = ctr % 2 == 0 ? "#FFCCCC" : "#CCCCFF" %>
### for PHP
<?php $color = $ctr % 2 == 0 ? "#FFCCCC" : "#CCCCFF"; ?>
### for JSTL 1.1
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="color" value="${ctr % 2 eq 0 ? '#FFCCCC' : '#CCCCFF'}"/>
### for JSTL 1.0
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<c:choose><c:when test="${ctr % 2 eq 0}">
<c:set var="color" value="#FFCCCC"/>
</c:when><c:otherwise>
<c:set var="color" value="#CCCCFF"/>
</c:otherwise></c:choose>
- (*2)
- Perlのように文字列用と数値用とで演算子が異なる言語に対しては、Kwartzを対応させるのは困難です。
出力
出力は「print(...);」で表します。
引数には任意の式を書くことができます。
PLプログラム:
print('foo', bar, "baz\n"); // 文字列と変数を出力
出力用スクリプト:
### for eRuby
foo<%= bar %>baz
### for PHP
foo<?php echo $bar; ?>baz
### for JSTL
foo<c:out value="${bar}" escapeXml="false"/>baz
自動サニタイズ機能を使用した場合は次のような出力になります。
### for eRuby
foo<%= CGI::escapeHTML((bar).to_s) %>baz
### for PHP
foo<?php echo htmlspecialchars($bar); ?>baz
### for JSTL
foo<c:out value="${bar}"/>baz
また自動サニタイズ機能を使用しても、条件演算子が返す値が文字列または数字である場合は、サニタイズされません。
PLプログラム:
// サニタイズされる
print("<option ", condition ? var1 : var2, ">\n");
// サニタイズされない(必要がないから)
print("<option ", condition ? 'selected' : '', ">\n");
出力用スクリプト:
### for eRuby
<option <%= CGI::escapeHTML((condition ? var1 : var2).to_s) %>>
<option <%= condition ? "selected" : "" %>>
### for PHP
<option <?php echo htmlspecialchars($condition ? $var1 : $var2); ?>>
<option <?php echo $condition ? "selected" : ""; ?>>
### for JSTL
<option <c:out value="${condition ? var1 : var2}"/>>
<option <c:out value="${condition ? 'selected' : ''}" escapeXml="false"/>>
代入
代入は「var = 100;」のように行います。
また、「+=」「-=」「*=」「/=」「%=」「.=」も使用できます。
PLプログラム:
name = 'Foo'; // 文字列を代入 count += 1; // 値を1増やす str .+= '.txt'; // 文字列の末尾に追加
出力用スクリプト:
### for PHP
<?php $name = "Foo"; ?>
<?php $count += 1; ?>
<?php $str .= ".txt"; ?>
### for eRuby
<% name = "Foo" %>
<% count += 1 %>
<% str += ".txt" %>
### for JSTL 1.1
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="name" value="Foo"/>
<c:set var="count" value="${count + 1}"/>
<c:set var="str" value="${fn:join(str,'.txt')}"/>
### for JSTL 1.0
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<c:set var="name" value="Foo"/>
<c:set var="count" value="${count + 1}"/>
<c:set var="str" value="${str}${'.txt'}"/>
配列、ハッシュ
配列は「arr[expr]」の形で参照できます。
ハッシュも同じ形で参照できます(*3)。
JSTLでは配列やハッシュの要素を参照することはできますが、配列やハッシュの要素に代入することはできません。
PLプログラム:
list[n] = 10; // n番目の要素に代入 print(list[i], "\n"); // i番目の要素を出力 hash['key'] = 'foo'; // ハッシュの要素に代入 print(hash['key'], "\n"); // ハッシュの要素を出力
出力用スクリプト:
### for eRuby <% list[n] = 10 %> <%= list[i] %> <% hash["key"] = "foo" %> <%= hash["key"] %> ### for PHP <?php $list[$n] = 10; ?> <?php echo $list[$i]; ?> <?php $hash["key"] = "foo"; ?> <?php echo $hash["key"]; ?>
ハッシュは、「hash[:key]」という形でも参照できます。
このとき、「key」は英数字と「_」のみからなる文字列である必要があります。
「hash[:key]」は、各プログラム言語に応じて次のように変換されます。
| ターゲット言語 | 変換結果 |
|---|---|
| eRuby | hash[:key] |
| PHP | $hash['key'] |
| JSTL | hash['key'] |
PLプログラム:
print(hash[:key]);
出力用スクリプト:
### for eRuby
<%= hash[:key] %>
### for PHP
<?php echo $hash['key']; ?>
### for JSTL
<c:out value="${hash['key']}" escapeXml="false"/>
- (*3)
- 配列とハッシュとで同じ演算子を用いているため、Perlのように異なる演算子を必要とするプログラミング言語への変換は困難です。
プロパティとメソッド
オブジェクトのプロパティは、「object.property」の形式で参照します。
また「object.method(arg1, arg2, ..)」のように引数をつけてメソッドを呼ぶこともできます。
ただし、メソッド呼び出しはJSTLではサポートしてませんので、JSTLへの変換時にはエラーになります。
PLプログラム:
// property user.name = 'Foo'; print(user.name, "\n");
出力用スクリプト:
### for eRuby
<% user.name = "Foo" %>
<%= user.name %>
### for PHP
<?php $user->name = "Foo"; ?>
<?php echo $user->name; ?>
### for JSTL
<c:set var="user" property="name" value="Foo"/>
<c:out value="${user.name}" escapeXml="false"/>
PLプログラム:
// method call print(user.method(10, 20));
出力用スクリプト:
### for eRuby <%= user.method(10, 20) %> ### for PHP <?php echo $user->method(10, 20); ?>
またPLではオブジェクトやプロパティを参照することはできても、オブジェクトを自分で生成したりクラスを定義したりすることはできません。 それらはPLの外部で(つまりメインプログラムの中で)行われることになります。
繰り返し
繰り返しは「foreach(loopvar in list) { ... }」で表します。
いわゆるforeach文であり、listの要素をひとつひとつloopvarに代入しながら繰り返しを行います。
PLプログラム:
foreach(item in list) { // listの要素をitemに代入しながら
print(item, "\n"); // 繰り返し出力する
}
出力用スクリプト:
### for eRuby
<% for item in list do %>
<%= item %>
<% end %>
### for PHP
<?php foreach ($list as $item) { ?>
<?php echo $item; ?>
<?php } ?>
### for JSTL
<c:forEach var="item" items="${list}">
<c:out value="${item}" escapeXml="false"/>
</c:forEach>
またwhile文も使用できます。 ただし、JSTLにはwhile文に相当するカスタムタグがないため、JSTLへ変換しようとするとエラーになります。
PLプログラム:
i = 0;
while(i < length) {
i += 1;
print(list[i]);
}
出力用スクリプト:
### for eRuby
<% i = 0 %>
<% while i < length do %>
<% i += 1 %>
<%= list[i] %><% end %>
### for PHP
<?php $i = 0; ?>
<?php while ($i < $length) { ?>
<?php $i += 1; ?>
<?php echo $list[$i]; ?><?php } ?>
なおJavaやCのようなfor文は用意されていません。ご注意ください。
条件分岐
条件分岐は「if(condition) { ... } else if(condition) { ... } else { ... }」で表します。
PLプログラム:
if (val > 0) {
print ("* value is positive.\n");
} else if (val < 0) {
print ("* value is negative.\n");
} else {
print ("* value is zero.\n");
}
出力用スクリプト:
### for eRuby
<% if val > 0 then %>
* value is positive.
<% elsif val < 0 then %>
* value is negative.
<% else %>
* value is zero.
<% end %>
### for PHP
<?php if ($val > 0) { ?>
* value is positive.
<?php } elseif ($val < 0) { ?>
* value is negative.
<?php } else { ?>
* value is zero.
<?php } ?>
### for JSTL
<c:choose><c:when test="${val gt 0}">
* value is positive.
</c:when><c:when test="${val lt 0}">
* value is negative.
</c:when><c:otherwise>
* value is zero.
</c:otherwise></c:choose>
関数
PLでは、以下の関数を使用することができます。
- E(expr)
- 式 expr をサニタイズします。サニタイズはコマンドラインオプションの指定に関わらず行われます。
- X(expr)
- 式 expr をサニタイズしません。つまりコマンドラインオプションでサニタイズするよう指定されていても、 X(expr)で指定された式はサニタイズされません。
- C(expression)
-
「
expression ? ' checked="checked"' : ''」と同じです。
- S(expression)
-
「
expression ? ' selected="selected"' : ''」と同じです。
- D(expression)
-
「
expression ? ' disabled="disabled"' : ''」と同じです。
- list_new()
- 新しいリストを作成します。
- list_length(list)
- リストlistの長さを返します。JSTL1.0では使用できません。
- hash_new()
- 新しいハッシュを作成します。
- hash_keys(hash)
- ハッシュの全キーをリストで返します。
- str_length(string)
- 文字列stringの長さを返します。
- str_tolower(string)
- 文字列stringを小文字にして返します。
- str_toupper(string)
- 文字列stringを大文字にして返します。
- str_trim(string)
- 文字列stringの前後から空白を取り除いた文字列を返します。
- str_index(string, char)
- 文字列stringにおいて文字charのある場所を返します。
ただし、JSTL1.0では関数をサポートしてないので、これらを使用することはできません(E()とX()を除く)。 JSTL1.1では関数をサポートしていますが、list_new()とhash_new()とhash_keys()には対応していません。
| 関数名 | PHP | eRuby | JSTL1.1 | JSTL1.0 |
|---|---|---|---|---|
list_new() |
[] |
array() |
- | - |
list_length(list) |
list.length |
array_length(list) |
fn:length(list) |
- |
hash_new() |
{} |
array() |
- | - |
hash_keys(hash) |
hash.keys |
array_keys(hash) |
- | - |
str_length(str) |
str.lenth |
strlen(str) |
fn:length(str) |
- |
str_tolower(str) |
str.downcase |
strtolower(str) |
fn:toLowerCase(str) |
- |
str_toupper(str) |
str.upcase |
strtoupper(str) |
fn:toUpperCase(str) |
- |
str_index(str,ch) |
str.index(ch) |
strchr(str,ch) |
fn:indexOf(str,ch) |
- |
これら以外の関数は、PHPまたはeRubyに変換するときはそのまま出力されます。 JSTLではユーザ定義の関数が使用できませんので、JSPへの変換はエラーになります。
E()とX()は、print文の引数として使われることを想定しています。 それ以外の場所では使わないでください。
empty
値がnullまたは空文字列かどうかを調べるための予約語「empty」を用意しています。
「empty」は「==」または「!=」の右辺にのみ置くことができ、左辺がnullか空文字列なら真を、それ以外なら偽を返します。
PLプログラム:
if (str1 == empty) {
print("str1 is empty.\n");
} else if (str2 != empty) {
print("str2 is not empty.\n");
}
出力用スクリプト:
### for eRuby
<% if !str1 || str1.empty? then %>
str1 is empty.
<% elsif str2 && !str2.empty? then %>
str2 is not empty.
<% end %>
### for PHP
<?php if (!$str1) { ?>
str1 is empty.
<?php } elseif ($str2) { ?>
str2 is not empty.
<?php } ?>
### for JSTL
<c:choose><c:when test="${empty str1}">
str1 is empty.
</c:when><c:when test="${not empty str2}">
str2 is not empty.
</c:when></c:choose>
エレメント宣言
エレメント宣言とは、「id="name"」または「id="mark:name"」でマーキングされたエレメントに対して、属性を操作したり、プレゼンテーションロジックを変更するための記述です。
Kwartzでは、プレゼンテーションロジックファイルはエレメント宣言の集合として記述されます。
エレメント宣言は、「#name」および複数の宣言部から構成されます。
-
value: expression; -
エレメントの内容を式
expressionの値で置き換えます。
-
attr: "attr1" expr1 , "attr2" expr2 , ... ; -
属性
attrの値を式exprで置き換えます。
-
remove: "attr1" , "attr2" , ... ; -
属性
attrを削除します。
-
append: expr1 , expr2 , ... ; -
タグに式
exprの値を追加します。 <input>タグや<option>タグにおいて「checked」や「selected」を追加するときに使用します。
-
tagname: expression; -
タグの名前を式
expressionで置き換えます。 StrutsやJSFのカスタムタグを利用するときに使用します。
-
plogic: { ... } -
プレゼンテーションロジックを記述します。
{ ... }の中では@stag、@cont、@etagが使用でき、それぞれ開始タグ、内容、終了タグを表します。 また@element(other)も使用でき、これはほかの名前がつけられたエレメントを展開することを表します。
プレゼンテーションデータ:
<ul> <li id="foo" class="foo">dummy</li> </ul> <form action="foo.cgi"> <input type="checkbox" name="user" value="Y" checked="checked" id="mark:chkbox"/> </form>
プレゼンテーションロジック:
#foo {
value: item;
attr: "class" klass;
plogic: {
foreach (item in list) {
@stag;
@cont;
@etag;
}
}
}
#chkbox {
remove: "checked";
append: flag ? " checked" : "";
tagname: "html:text";
}
出力用スクリプト:
### for eRuby
<ul>
<% for item in list do %>
<li id="foo" class="<%= klass %>"><%= item %></li>
<% end %>
</ul>
<form action="foo.cgi">
<html:text type="checkbox" name="user" value="Y"<%= flag ? " checked" : "" %> />
</form>
### for PHP
<ul>
<?php foreach ($list as $item) { ?>
<li id="foo" class="<?php echo $klass; ?>"><?php echo $item; ?></li>
<?php } ?>
</ul>
<form action="foo.cgi">
<html:text type="checkbox" name="user" value="Y"<?php echo $flag ? " checked" : ""; ?> />
</form>
### for JSTL 1.1
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<ul>
<c:forEach var="item" items="${list}">
<li id="foo" class="<c:out value="${klass}" escapeXml="false"/>"><c:out value="${item}" escapeXml="false"/></li>
</c:forEach>
</ul>
<form action="foo.cgi">
<html:text type="checkbox" name="user" value="Y"<c:out value="${flag ? ' checked' : ''}" escapeXml="false"/> />
</form>
ドキュメント宣言
#DOCUMENT { ... }は、ドキュメントのための特殊なエレメント宣言です。
この宣言はドキュメント全体の情報を表し、次の宣言部を使用します。
-
begin: { ... } - 出力用スクリプトの先頭に、指定されたPLコードを追加します。
-
end: { ... } - 出力用スクリプトの末尾に、指定されたPLコードを追加します。
-
require: "filename1" , "filename2", ... ; - プレゼンテーションロジックファイルを読み込みます。
-
global: varname1 , varname2 , ... ; - グローバル変数を列挙します。現在は何も使われていませんが、将来は使う予定です。
-
local: varname1 , varname2 , ... ; - ローカル変数を列挙します。現在は何も使われていませんが、将来は使う予定です。
プレゼンテーションデータ:
<ul id="mark:list"> <li id="value:item">foo</li> </ul>
PLプログラム:
#DOCUMENT {
begin: {
list = context[:list];
}
end: {
print("<!-- copyright(c) 2005 kuwata-lab.com ALL RIGHTS RESERVERD. -->\n");
}
global: context;
}
#list {
plogic: {
@stag;
foreach (item in list)
@cont;
@etag;
}
}
出力用スクリプト:
### for eRuby
<% list = context[:list] %>
<ul>
<% for item in list do %>
<li><%= item %></li>
<% end %>
</ul>
<!-- copyright(c) 2005 kuwata-lab.com ALL RIGHTS RESERVERD. -->
### for PHP
<?php $list = $context['list']; ?>
<ul>
<?php foreach ($list as $item) { ?>
<li><?php echo $item; ?></li>
<?php } ?>
</ul>
<!-- copyright(c) 2005 kuwata-lab.com ALL RIGHTS RESERVERD. -->
### for JSTL
<c:set var="list" value="${context['list']}"/>
<ul>
<c:forEach var="item" items="${list}">
<li><c:out value="${item}" escapeXml="false"/></li>
</c:forEach>
</ul>
<!-- copyright(c) 2005 kuwata-lab.com ALL RIGHTS RESERVERD. -->
ターゲット言語のプログラムコード
ターゲット言語のプログラムコードを直接記述することもできます。
Kwartzでは、「<?」または「<%」で始まる行があれば行末までをターゲット言語のコードと判断し、
そのまま出力します。
次の例は、PHPのコードを直接記述した例です。
PLプログラム:
<?php foreach($hash as $key => $value) { ?>
print("key=", key, " value=", value, "\n");
<?php } ?>
出力用スクリプト:
### for PHP
<?php foreach($hash as $key => $value) { ?>
key=<?php echo $key; ?> value=<?php echo $value; ?>
<?php } ?>
Raw-codeは、エレメント宣言の「plogic:」部、またドキュメント宣言の「begin:」部や「end:」部に記述できます。 つまり、プレゼンテーションロジックをターゲット言語で記述できます。
プレゼンテーションロジック:
#foo {
plogic: {
@stag;
<% hash.each do |key, value| %>
@cont;
<% end %>
@etag;
}
}
ただし、Raw-codeをエレメント宣言の「value:」部や「attr:」部に記述することはできません。 Raw-codeは文(statement)であり式(expression)ではないためです。
ターゲット言語のプログラムコードを直接記述した場合は、当然ですが他の言語では使用できなくなります。 それでも構わない場合にのみ使用してください。
グローバル変数とローカル変数
Kwartzでは、メインプログラムから出力用プログラムに渡される変数をグローバル変数、テンプレートの中だけで使用される変数をローカル変数と呼んでいます。
例えば次のようなプレゼンテーションデータとプレゼンテーションロジックを考えます。
プレゼンテーションデータ(analyze.html):
<table>
<caption id="value:title">Sample</caption>
<tr id="mark:items" bgcolor="@{color}@">
<td id="value:item">Foo</td>
</tr>
</table>
プレゼンテーションロジック(analyze.plogic):
#items {
plogic: {
ctr = 0;
foreach (item in list) {
ctr += 1;
color = ctr%2 == 0 ? '#FFCCCC' : '#CCCCFF';
@stag;
@cont;
@etag;
}
}
}
いくつかの変数がでてきますが、これらは次のように分類できます。
- グローバル変数
-
変数「
title」と「list」は、メインプログラムからテンプレートに渡される変数であり、メインプログラムで値を設定する必要があります。 Kwartzではこれをグローバル変数と呼んでいます。 - ローカル変数
-
変数「
item」と「ctr」と「color」はテンプレートの中だけで使用される変数であり、メインプログラムで設定する必要はありません。 Kwartzではこれをローカル変数と呼んでいます。
kwartzコマンドにオプション「-a analyze」をつけて起動すると、テンプレートを分析してグローバル変数とローカル変数を報告してくれます。
$ kwartz -p analyze.plogic -a analyze analyze.html Global: title list Local: ctr item color
このとき、Kwartzは次のようなルールでグローバル変数とローカル変数とを判別しています。
- 変数が初めて現れたときに…
- 代入文の左辺に現れた変数はローカル変数
- foreach文のループ変数として現れた変数はローカル変数
- それ以外はグローバル変数
またグローバル変数へ代入したり、グローバル変数をループ変数としていると、分析時に警告を出します。 なぜなら、テンプレートシステムはメインプログラムで設定されたデータの表示のみを行うべきであり、それらを変更すべきではないから、つまりグローバル変数を変更すべきではないからです(変更してよいのはローカル変数のみのはずです)。
テンプレート(プレゼンテーションデータとプレゼンテーションロジック)が複雑になると、メインプログラムで設定しなければならない変数がどれか、わかりづらくなることがあります。 そのようなときは、この分析機能を利用してください。変数名のタイプミスも見つけやすくなります。
未実装(または検討中)の機能
以下の機能は実装されていませんが、将来において実装されるかもしれません。
- break, continue
- ユーザ定義関数
- JSTLにおける配列やハッシュの作成
ディレクティブ
ディレクティブとは?
Kwartzでは、プレゼンテーションデータの中にプレゼンテーションロジックを埋め込むこともできます。 そのための命令を「ディレクティブ(Directive)」といいます。
ディレクティブとは、プレゼンテーションデータの中にプレゼンテーションロジックを埋め込むための命令です。
Kwartzでは、ディレクティブはid属性またはid属性を使用します(使い方はどちらも同じです)。
「id="name"」や「id="mark:name"」も、「マーキング」というディレクティブです。
Kwartzではせっかくプレゼンテーションデータとプレゼンテーションロジックとを分離することができるのに、なぜ両者を一体化するような機能も用意されているのでしょう?
それは、開発者の好みに応じてどちらも選べるようにするため、つまり「選択可能性(choosability)」を高めるためです。 Kwartzは、開発者にどちらか一方を押しつけるようなことはしません。 分離するほうが望ましいのであれば分離すればよいし、一体化するほうが好みであれば一体化すればよいのです。
また両者を一体化すると、他のテンプレートと差別化できないと思われるかもしれません。 しかし一体化してもなお、Kwartzは他のテンプレートと比べて次のような利点があります。
- HTMLデザインを崩しません(Jakarta VelocityやTemplate-Toolkitと比べてみてください)。
- 複雑なプログラミングが必要ありません(DOMプログラミングが必要なEnhydra XMLCと比べてみてください)。
- 実行時の動作が軽くて高速です(amritaと比べてみてください)。
- XMLやHTMLだけでなく、どのようなテキスト形式でも利用できます(Enhydra XMLCやamritaと比べて見てください)。
- 各種のプログラミング言語で使用できます(このようなテンプレートシステムは他にありません!)。
マーキング
「id="name"」または「id="mark:name"」とすることで、マーキングを行います。
マーキングとは、エレメントに対してその名前で目印をつけることです。
「id="name"」と「id="mark:name"」との違いは、コンパイルされると前者ではid属性が残るのに対し後者は取り除かれるという点です。
またkw:d属性は必ず取り除かれます。
プレゼンテーションデータ:
<div id="foo">foo</div> <div id="mark:bar">bar</div>
出力用スクリプト:
### for eRuby <div id="foo">foo</div> <div>bar</div> ### for PHP <div id="foo">foo</div> <div>bar</div> ### for JSTL <div id="foo">foo</div> <div>bar</div>
値の出力
「@{expression}@」は、式の値を出力するディレクティブです。
このパターンは、設定ファイルのEMBED_PATTERNに設定されています。
プレゼンテーションデータ:
Hello @{user.name}@!
出力用プログラム:
### for eRuby
Hello <%= user.name %>!
### for PHP
Hello <?php echo $user->name; ?>!
### for JSTL
Hello <c:out value="${user.name}" escapeXml="false"/>!
コンパイル時に、コマンドオプション-eを指定した場合は、式をサニタイズして出力します。
このとき、文字列や数値はサニタイズされず、式のみがサニタイズされることに注意してください。
出力用プログラム(コマンドオプション-eをつけた場合):
### for eRuby
Hello <%= CGI::escapeHTML((user.name).to_s) %>!
### for PHP
Hello <?php echo htmlspecialchars($user->name); ?>!
### for JSTL
Hello <c:out value="${user.name}"/>!
コマンドオプションの有無に関わらずサニタイズをする/しないを指定するには、関数E()とX()を使用します。
E(expr)は式exprをサニタイズし、X(expr)はサニタイズしません。
プレゼンテーションデータ:
With sanitizing: @{E(var)}@!
Without sanitizing: @{X(var)}@!
出力用プログラム:
### for eRuby
With sanitizing: <%= CGI::escapeHTML((var).to_s) %>!
Without sanitizing: <%= var %>!
### for PHP
With sanitizing: <?php echo htmlspecialchars($var); ?>!
Without sanitizing: <?php echo $var; ?>!
### for JSTL
With sanitizing: <c:out value="${var}"/>!
Without sanitizing: <c:out value="${var}" escapeXml="false"/>!
. .
値の出力2
「id="value:expression"」とすることで、内容のかわりに式の値を出力します。
ダミーデータを利用できるため、「@{expression}@」と比べてHTMLデザインがより崩れません。
プレゼンテーションデータ:
<li id="value:hash['name']">foo</li>
出力用プログラム:
### for eRuby
<li><%= hash["name"] %></li>
### for PHP
<li><?php echo $hash["name"]; ?></li>
### for JSTL
<li><c:out value="${hash['name']}" escapeXml="false"/></li>
また「id="Value:expr"」でサニタイズすることを、「id="VALUE:expr"」でサニタイズしないことを指定できます。
これらはそれぞれ「id="value:E(expr)"」や「id="value:X(expr)"」と同じです。
属性値の設定
「id="attr:name=value"」または「id="attr:name:value"」とすることで、タグの属性値を設定できます。
これを用いると、「@{...}@」を使わずに属性値を設定でき、またダミーの属性値を設定できます。
次の例では、属性classにダミーの属性値 "odd" を設定していますが、実際には変数klassの値を用いるようにしています。
プレゼンテーションデータ:
<tr class="odd" id="attr:class=klass"> <td>foo</td> </tr>
出力用プログラム:
### for eRuby
<tr class="<%= klass %>">
<td>foo</td>
</tr>
### for PHP
<tr class="<?php echo $klass; ?>">
<td>foo</td>
</tr>
### for JSTL
<tr class="<c:out value="${klass}" escapeXml="false"/>">
<td>foo</td>
</tr>
また「id="Attr:name=value"」でサニタイズすることを、「id="ATTR:name=value"」でサニタイズしないことを指定できます。
これらはそれぞれ「id="attr:name=E(value)"」や「id="attr:name=X(value)"」と同じです。
なお「;」で区切ることにより、「attr:name=value」を複数設定したり他のテンプレートコマンドと一緒に設定したりできます。
プレゼンテーションデータ:
<font id="if:message!=empty;attr:class=klass;attr:bgcolor=color">
@{message}@
</font>
出力用スクリプト:
### for eRuby
<% if message && !message.empty? then %>
<font class="<%= klass %>" bgcolor="<%= color %>">
<%= message %>
</font>
<% end %>
### for PHP
<?php if ($message) { ?>
<font class="<?php echo $klass; ?>" bgcolor="<?php echo $color; ?>">
<?php echo $message; ?>
</font>
<?php } ?>
### for JSTL
<c:if test="${not empty message}">
<font class="<c:out value="${klass}" escapeXml="false"/>" bgcolor="<c:out value="${color}" escapeXml="false"/>">
<c:out value="${message}" escapeXml="false"/>
</font>
</c:if>
属性の追加
「id="append:expression"」とすることで、タグの中に式の値を追加できます。
これは主に「<input ... checked />」や「<option ... selected></option>」を実現するための機能です。
プレゼンテーションデータ:
<option name="lang" value="ruby"
id="append:lang=='ruby'?' selected':''">Ruby</option>
<input type="radio" name="gender" value="M"
id="append:gender=='M'?' checked':''">
出力用スクリプト:
### for eRuby
<option name="lang" value="ruby"<%= lang == "ruby" ? " selected" : "" %>>Ruby</option>
<input type="radio" name="gender" value="M"<%= gender == "M" ? " checked" : "" %>>
### for PHP
<option name="lang" value="ruby"<?php echo $lang == "ruby" ? " selected" : ""; ?>>Ruby</option>
<input type="radio" name="gender" value="M"<?php echo $gender == "M" ? " checked" : ""; ?>>
### for JSTL 1.1
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<option name="lang" value="ruby"<c:out value="${lang eq 'ruby' ? ' selected' : ''}" escapeXml="false"/>>Ruby</option>
<input type="radio" name="gender" value="M"<c:out value="${gender eq 'M' ? ' checked' : ''}" escapeXml="false"/>>
### for JSTL 1.0
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<c:choose><c:when test="${lang eq 'ruby'}">
<option name="lang" value="ruby" selected></c:when><c:otherwise>
<option name="lang" value="ruby"></c:otherwise></c:choose>
Ruby</option>
<c:choose><c:when test="${gender eq 'M'}">
<input type="radio" name="gender" value="M" checked>
</c:when><c:otherwise>
<input type="radio" name="gender" value="M">
</c:otherwise></c:choose>
なお「checked="checked"」「selected="selected"」「disabled="disabled"」の出力を簡単にするための機能として、関数「C(expr)」「S(expr)」「D(expr)」が用意されています。
これらは、式exprが真のときにそれぞれ「checked="checked"」「selected="selected"」「disabled="disabled"」を出力します。
プレゼンテーションデータ:
<option name="lang" value="ruby"
id="append:S(lang=='ruby')">Ruby</option>
<input type="radio" name="gender" value="M"
id="append:C(gender=='M')" />Male
<input type="radio" name="os" value="win"
id="append:D(os=='mac')" />Windows
出力用スクリプト:
### for PHP
<option name="lang" value="ruby"<?php echo $lang == "ruby" ? " selected=\"selected\"" : ""; ?>>Ruby</option>
<input type="radio" name="gender" value="M"<?php echo $gender == "M" ? " checked=\"checked\"" : ""; ?> />Male
<input type="radio" name="os" value="win"<?php echo $os == "mac" ? " disabled=\"disabled\"" : ""; ?> />Windows
### for eRuby
<option name="lang" value="ruby"<%= lang == "ruby" ? " selected=\"selected\"" : "" %>>Ruby</option>
<input type="radio" name="gender" value="M"<%= gender == "M" ? " checked=\"checked\"" : "" %> />Male
<input type="radio" name="os" value="win"<%= os == "mac" ? " disabled=\"disabled\"" : "" %> />Windows
### for JSTL 1.1
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<option name="lang" value="ruby"<c:out value="${lang eq 'ruby' ? ' selected="selected"' : ''}" escapeXml="false"/>>Ruby</option>
<input type="radio" name="gender" value="M"<c:out value="${gender eq 'M' ? ' checked="checked"' : ''}" escapeXml="false"/> />Male
<input type="radio" name="os" value="win"<c:out value="${os eq 'mac' ? ' disabled="disabled"' : ''}" escapeXml="false"/> />Windows
### for JSTL 1.0
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<c:choose><c:when test="${lang eq 'ruby'}">
<option name="lang" value="ruby" selected="selected"></c:when><c:otherwise>
<option name="lang" value="ruby"></c:otherwise></c:choose>
Ruby</option>
<c:choose><c:when test="${gender eq 'M'}">
<input type="radio" name="gender" value="M" checked="checked" /></c:when><c:otherwise>
<input type="radio" name="gender" value="M" /></c:otherwise></c:choose>
Male
<c:choose><c:when test="${os eq 'mac'}">
<input type="radio" name="os" value="win" disabled="disabled" /></c:when><c:otherwise>
<input type="radio" name="os" value="win" /></c:otherwise></c:choose>
Windows
変数への代入
「id="set:var=value"」は、変数varに値valueを設定します。
「=」だけでなく「+=」「-=」「*=」「/=」「.=」が使用できます。
プレゼンテーションデータ:
<dt id="set:var=value">foo</dt> <dd id="set:count+=1">123</dd>
出力用プログラム:
### for eRuby
<% var = value %>
<dt>foo</dt>
<% count += 1 %>
<dd>123</dd>
### for PHP
<?php $var = $value; ?>
<dt>foo</dt>
<?php $count += 1; ?>
<dd>123</dd>
### for JSTL
<c:set var="var" value="${value}"/>
<dt>foo</dt>
<c:set var="count" value="${count + 1}"/>
<dd>123</dd>
条件分岐
「id="if:expression"」とすることで、条件分岐を行います。
elseやelseifも使用できます。
プレゼンテーションデータ:
<div id="if:value > 0"> Value is positive. </div> <div id="elseif:value < 0"> Value is negative. </div> <div id="else:"> Value is zero. </div>
出力用プログラム:
### for eRuby
<% if value > 0 then %>
<div>
Value is positive.
</div>
<% elsif value < 0 then %>
<div>
Value is negative.
</div>
<% else %>
<div>
Value is zero.
</div>
<% end %>
### for PHP
<?php if ($value > 0) { ?>
<div>
Value is positive.
</div>
<?php } elseif ($value < 0) { ?>
<div>
Value is negative.
</div>
<?php } else { ?>
<div>
Value is zero.
</div>
<?php } ?>
### for JSTL
<c:choose><c:when test="${value gt 0}">
<div>
Value is positive.
</div>
</c:when><c:when test="${value lt 0}">
<div>
Value is negative.
</div>
</c:when><c:otherwise>
<div>
Value is zero.
</div>
</c:otherwise></c:choose>
「elseif」や「else」を使う場合は、直前に空行を入れないようにしてください。
繰り返し(foreach)
「id="foreach:loopvar=list"」(または「id="foreach:loopvar:list"」)とすることで、リストlistの要素をひとつずつ変数loopvarに代入しながら、繰り返しを行います。
プレゼンテーションデータ:
<tr id="foreach:item=list">
<td>@{item}@</td>
</tr>
出力用プログラム:
### for eRuby
<% for item in list do %>
<tr>
<td><%= item %></td>
</tr>
<% end %>
### for PHP
<?php foreach ($list as $item) { ?>
<tr>
<td><?php echo $item; ?></td>
</tr>
<?php } ?>
### for JSTL
<c:forEach var="item" items="${list}">
<tr>
<td><c:out value="${item}" escapeXml="false"/></td>
</tr>
</c:forEach>
繰り返し(loop)
「id="loop:loopvar=list"」(または「id="loop:loopvar:list"」)とすることで、リストlistの要素をひとつずつ変数loopvarに代入しながら繰り返しを行います。
「id="foreach:loopvar=list)"」とよく似ていますが、開始タグと終了タグを含めず、内容だけ繰り返す点が異なります。
<dl></dl>で使うと非常に便利です。
プレゼンテーションデータ:
<dl id="loop:item=list">
<dt>@{item.text}@</dt>
<dd>@{item.desc}@</dd>
</dl>
出力用プログラム:
### for eRuby
<dl>
<% for item in list do %>
<dt><%= item.text %></dt>
<dd><%= item.desc %></dd>
<% end %>
</dl>
### for PHP
<dl>
<?php foreach ($list as $item) { ?>
<dt><?php echo $item->text; ?></dt>
<dd><?php echo $item->desc; ?></dd>
<?php } ?>
</dl>
### for JSTL
<dl>
<c:forEach var="item" items="${list}">
<dt><c:out value="${item.text}" escapeXml="false"/></dt>
<dd><c:out value="${item.desc}" escapeXml="false"/></dd>
</c:forEach>
</dl>
カウンタつき繰り返し(Foreach,Loop)
「id="Foreach:var=list)"」や「id="Loop:var=list)"」を使うと、カウンタを増やしながら繰り返しを行います。
カウンタは1から始まり、変数名はvar_ctrです。
プレゼンテーションデータ:
<tr id="Foreach:item=list">
<td>@{item_ctr}@</td>
<td>@{item}@<td>
</tr>
出力用プログラム:
### for eRuby
<% item_ctr = 0 %>
<% for item in list do %>
<% item_ctr += 1 %>
<tr>
<td><%= item_ctr %></td>
<td><%= item %><td>
</tr>
<% end %>
### for PHP
<?php $item_ctr = 0; ?>
<?php foreach ($list as $item) { ?>
<?php $item_ctr += 1; ?>
<tr>
<td><?php echo $item_ctr; ?></td>
<td><?php echo $item; ?><td>
</tr>
<?php } ?>
### for JSTL
<c:set var="item_ctr" value="0"/>
<c:forEach var="item" items="${list}">
<c:set var="item_ctr" value="${item_ctr + 1}"/>
<tr>
<td><c:out value="${item_ctr}" escapeXml="false"/></td>
<td><c:out value="${item}" escapeXml="false"/><td>
</tr>
</c:forEach>
トグルつき繰り返し(FOREACH,LOOP)
「id="FOREACH:var=list"」や「id="LOOP:var=list"」とすると、トグルつきの繰り返しを行うことができます。
トグルは、繰り返し回数が奇数回か偶数回かによって、値が入れ替わります。
トグル変数の名前はvar_tglです。
トグルの値はデフォルトで「"odd"」と「"even"」が使われますが、コマンドオプション --odd と --even で指定できます。
また設定ファイルkwartz/config.rbの定数ODDとEVENでも指定できます。
プレゼンテーションデータ:
<table>
<tbody id="LOOP:item=list">
<tr class="@{item_tgl}@">
<td>@{item}@</td>
</tr>
</tbody>
</table>
出力用プログラム:
### for eRuby
<table>
<tbody>
<% item_ctr = 0 %>
<% for item in list do %>
<% item_ctr += 1 %>
<% item_tgl = item_ctr % 2 == 0 ? "even" : "odd" %>
<tr class="<%= item_tgl %>">
<td><%= item %></td>
</tr>
<% end %>
</tbody>
</table>
### for PHP
<table>
<tbody>
<?php $item_ctr = 0; ?>
<?php foreach ($list as $item) { ?>
<?php $item_ctr += 1; ?>
<?php $item_tgl = $item_ctr % 2 == 0 ? "even" : "odd"; ?>
<tr class="<?php echo $item_tgl; ?>">
<td><?php echo $item; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
### for JSTL
<table>
<tbody>
<c:set var="item_ctr" value="0"/>
<c:forEach var="item" items="${list}">
<c:set var="item_ctr" value="${item_ctr + 1}"/>
<c:set var="item_tgl" value="${item_ctr % 2 eq 0 ? 'even' : 'odd'}"/>
<tr class="<c:out value="${item_tgl}" escapeXml="false"/>">
<td><c:out value="${item}" escapeXml="false"/></td>
</tr>
</c:forEach>
</tbody>
</table>
繰り返し(while)
「id="while:expression"」とすることで、繰り返しを行うことができます。
またJSPでは、whileを変換しようとするとエラーになります。 これは、whileに対応するカスタムタグがないからです。
プレゼンテーションデータ:
<tr id="while:row=sth.fetch()">
<td>@{row[0]}@</td>
</tr>
出力用プログラム:
### for eRuby
<% while row = sth.fetch() do %>
<tr>
<td><%= row[0] %></td>
</tr>
<% end %>
### for PHP
<?php while ($row = $sth->fetch()) { ?>
<tr>
<td><?php echo $row[0]; ?></td>
</tr>
<?php } ?>
ダミーデータ
「id="dummy:str"」とすることで、そのノードをダミーデータとみなして読み飛ばします。
strは、id属性の値が重ならないようにするためのものであり、意味はありません。
プレゼンテーションデータ:
<tr id="dummy:d1"> <td>bar</td> </tr> <tr id="dummy:d2"> <td>baz</td> </tr>
中間コード:
// 何も出力されない
出力用プログラム:
// 何も出力されない
エレメントの置換
「id="replace:name"」とすることで、そのエレメントを別のエレメントに置き換えることができます。
プレゼンテーションデータ:
<html>
<body>
<!-- ナビゲーション -->
<div id="mark:breadcrumbs">
<a href="/">Home</a>
> <a href="/kwartz">Kwartz</a>
> <a href="/kwartz/ruby">Kwartz-ruby</a>
</div>
....
<div id="replace:breadcrumbs">
Home > Kwartz > Kwartz-ruby
</span>
</div>
</html
出力用スクリプト:
<html>
<body>
<!-- ナビゲーション -->
<div>
<a href="/">Home</a>
> <a href="/kwartz">Kwartz</a>
> <a href="/kwartz/ruby">Kwartz-ruby</a>
</div>
....
<div>
<a href="/">Home</a>
> <a href="/kwartz">Kwartz</a>
> <a href="/kwartz/ruby">Kwartz-ruby</a>
</div>
</html
なおコマンドラインオプション「-i file1,file2,...」を指定すると、
他のファイルのエレメントを利用できます。
プレースホルダ
「id="placeholder:name"」とすることで、そのエレメントの内容を別のエレメントで置き換えます。
通常は、コマンドラインオプション「-i file1,file2,...」とともに使用し、
他のファイルで定義されたエレメントを取り込むために使われます。
プレゼンテーションデータ(article.html):
<html>
<body>
<div id="mark:article">
<p>Kwartz is a template system, which realized the
concept <strong>`Separation of Presentation Logic
and Presentation Data'(SoPL/PD)</strong>.
</p>
</div>
</body>
</html>
プレゼンテーションデータ(layout.html):
<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" type="text/css" href="design.css">
</head>
<body>
<table border="0">
<tr>
<td width="400" id="placeholder:article">
aaa<br>
bbb<br>
ccc<br>
ddd<br>
</td>
</tr>
</table>
</body>
</html>
コンパイル:
$ kwartz -i article.html layout.html
出力用スクリプト:
<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" type="text/css" href="design.css">
</head>
<body>
<table border="0">
<tr>
<td width="400">
<div>
<p>Kwartz is a template system, which realized the
concept <strong>`Separation of Presentation Logic
and Presentation Data'(SoPL/PD)</strong>.
</p>
</div>
</td>
</tr>
</table>
</body>
</html>
プレゼンテーションデータファイルの読み込み
「id="include:filename"」で他のプレゼンテーションデータファイル(HTMLファイル)を読み込むことができます。
読み込まれる側のファイルでも、ディレクティブを使用できます。
プレゼンテーションデータ(copyright.html):
<!-- begin footer --> <center> copyright© <span id="value:year">2005</span> kuwata-lab all rights reserverd </center> <!-- end footer -->
プレゼンテーションデータ(mainpage.html):
<html>
<body>
... main contents ...
<div id="include:copyright.html">
... copyright ...
</div>
</body>
</html>
コンパイル:
$ kwartz -l eruby mainpage.html > mainpage.view
出力用スクリプト:
### for eRuby
<html>
<body>
... main contents ...
<!-- begin footer -->
<center>
copyright© <%= year %> kuwata-lab all rights reserverd
</center>
<!-- end footer -->
</body>
</html>
「include」ディレクティブのほかに、「Include」と「INCLUDE」が使用できます。
- 「
include」ディレクティブは、読み込んだファイルでそのエレメントを置き換えます。 - 「
Include」ディレクティブは、読み込んだファイルをそのエレメントの前に追加します。 - 「
INCLUDE」ディレクティブは、読み込んだファイルをそのエレメントの後ろに追加します。
includeディレクティブで読み込むファイルは、別ディレクトリに置くことができます。
ファイルが置いてあるディレクトリは、コマンドラインオプション --incdirs=dir1,dir2,...
または設定ファイルの INCDIRS で指定できます。
id属性とkw:d属性について
Kwartzでは、ディレクティブを記述するのにid属性とkw:d属性が使用できます。 ここでは、両者の使い分けについて説明します。
- id属性もkw:d属性も、機能としては同じです。
今までid属性で説明していましたが、すべてkw:d属性に書いても動作します。
- ひとつのタグにid属性とkw:d属性の両方を記述した場合、kw:d属性のほうが優先されます。
例えば「
id="name" kw:d="foreach:item=list"」とした場合、kw:d属性のほうが有効となります。
- ただし、kw:d属性に記述したディレクティブが
attrのみの場合は、 id属性のディレクティブも有効となります。 例えば「id="name" kw:d="attr:href=url"」とした場合、そのエレメントは名前nameを使ってマーキングされます。
- HTMLの仕様では、id属性の値に含めることのできる記号はアンダーバー(
_)、コロン(:)、ピリオド(.)、ハイフン(-)のみです。 そのため、id="foreach:item=list"やid="attr:name=value"という記述はHTMLの仕様からみると正しくありませんので、id="foreach:item:list"やid="attr:name:value"と書くほうがよいでしょう。
- kw:d属性の名前は、コマンドラインオプション
--dattr=xxxで変更することができます。 例えばkw:d属性のかわりにstyle属性を使う場合は、 --dattr=style としてください。 また設定ファイルのDATTRでも変更できます。
注意事項
ディレクティブを使用する際の注意事項です。
- ひとつのid属性またはkw:d属性にはひとつのディレクティブしか記述できません。
例えば「
id="set:var=100;value:var"」のような記述はエラーになります。## NG <span id="set:var=100;value:var">foo</span>
- ただし、attrディレクティブとappendディレクティブだけは他のディレクティブといっしょに記述できます。
また複数のattrディレクティブとappendディレクティブを設定することもできます。
## OK <foo id="foreach:item=list;attr:class=item.class;attr:href=item.url"> .... </foo>
- タグにディレクティブを含めた場合、終了タグは省略できません。
また
<foo .../>のような空要素タグは使用できます。## NG <ul> <li id="value:item">foo </ul> ## OK <a id="attr:name=refname"/>
- ディレクティブしか含まないような<span></span>は、削除されます。
例えば「
Hello <span id="value:name">World</span>!」というプレゼンテーションデータは、<span></span>が削除されて「Hello <%= name %>!」(eRubyの場合)という出力ファイルになります。## プレゼンテーションデータ Hello <span id="value:name">World</span>! ## 出力用スクリプト for eRuby Hello <%= name %>!
- ディレクティブを含むタグでは、ほかの属性は必ず「
attr="value"」の形で記述し、属性名や属性値を省略しないようにしてください。 これはHTML/XML以外でもKwartzを使用できるようにするための意図した仕様であり、バグではありません。## NG <input type="checkbox" id="foreach:item=list" checked/> ## OK <input type="checkbox" id="foreach:item=list" checked="checked"/> ## NG <option id="attr:value=val" @{flag ? 'selected' : ''}@/> ## OK <option value="@{val}@" @{flag ? 'selected' : ''}@>
コマンドラインオプション
テンプレートを出力用プログラムへコンパイルするには、kwartzコマンドを使用します。
使い方:
kwartz [options...] [-p plogic ] pdata.html > output-script
オプションは次の通りです。
- -h, --help
- ヘルプを表示。
- -v
- バージョン情報を表示
- -a action
-
実行する処理。actionには次のどれかを指定する(デフォルトはcompile)。
- compile
- プレゼンテーションデータとプレゼンテーションロジックを読み込み、出力用スクリプトを生成します。
- analyze
- プレゼンテーションデータとプレゼンテーションロジックを読み込み、変数のスコープを解析します。
- convert
- プレゼンテーションデータを読み込み、PLプログラムに変換します。デバッグ用です。
- transalte
- PLプログラムを読み込み、出力用スクリプトに変換します。デバッグ用です。
- -e , -s
-
サニタイズを行う。
--escape=trueと同じ。
- -i file1,file2,...
-
外部ファイルで定義されたエレメントをインポートする。
主にplaceholderディレクティブ(「
id="placeholder:name」)のために使用される。
- -l lang
- ターゲット言語を指定。指定できるのは eruby, erb, php, jstl11, jstl10.
- -p plogic-file
-
プレゼンテーションロジックのファイル名。「
,」で区切ることで、複数のファイル名を指定できる。
- --charset=charset
-
文字コード。JSTLにおいて '
<%@ page contentType="text/html; charset=charset "%>' を出力する。
- --dname=name
- ディレクティブで使用する属性名。デフォルトは 'kw:d'。
- --escape=true|false
- 式をサニタイズして出力する。値が省略されたときはtrueが指定されたものとみなす。
- --even=value
-
偶数のときの値。デフォルトは「
'even'」。ディレクティブFOREACHとLISTで使われる。
- --extract=name
- 指定された名前でマーキングされたエレメントだけを抽出する。
- --footer=string
- フッター文字列。
- --header=string
-
ヘッダー文字列。
JSPではデフォルトで '
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>' が設定される。 これを出力したくないときは--header=falseとする。
- --indent=' '
- 出力用スクリプトのインデントを指定する。
- --incdirs=dir1,dir2,...
-
includeディレクティブで読み込むファイル(プレゼンテーションデータファイル)のディレクトリを指定する。
- --odd=value
-
奇数のときの値。デフォルトは「
'odd'」。ディレクティブFOREACHとLISTで使われる。
- --rename=true|false
- ローカル変数名を変更するかどうかを指定する。値が省略されたときはtrueとみなされる。
使い方の例です。
- プレゼンテーションデータ(file1.html)をコンパイルして、出力用スクリプト(file1.php)に変換する。
ターゲット言語はeRuby。
$ kwartz -l eruby file1.html > file1.rhtml
- プレゼンテーションデータ(file1.html)とプレゼンテーションロジック(file1.plogic)から、出力用スクリプト(file1.php)を作成する。
ターゲット言語はPHP。
$ kwartz -l php -p file1.plogic file1.html > file1.php
- プレゼンテーションデータをPLプログラムにコンバートする。
$ kwartz -a convert file1.html | more
設定オプション
設定ファイルで、Kwartzのオプションを指定できます。 Kwartzの設定ファイルは、実装ごとに異なります。 Kwartz-rubyでは、kwartz/config.rbです。
設定ファイルでは、以下のオプションが設定できます。
- ESCAPE
- 自動サニタイズをデフォルトでオンにするか、オフにするかを指定します。
- NEWLINE
- 改行を表す文字列を指定します。 ただし、Kwartzは改行が「\n」か「\r\n」かを自動判別することができるので、通常は変更する必要はありません。
- INDENT
- インデントとして使う空白文字列を指定します。
- RENAME
- ローカル変数の名前を変更するかどうかを指定します。 trueなら、ローカル変数名の頭に「_」をつけます。
- RENAME_PREFIX
- ローカル変数の頭につける文字列を指定します。
- LANG
- デフォルトの出力用言語を指定します。
- ODD
-
トグル変数の奇数値を指定します。
「
id="FOREACH:var=list"」と「id="LOOP:var=list"」で使用されます。
- EVEN
-
トグル変数の偶数値を指定します。
「
id="FOREACH:var=list"」と「id="LOOP:var=list"」で使用されます。
- DATTR
-
ディレクティブで使用する属性名を指定します。デフォルトは
kw:dです。
- NOEND
- 終了タグを必要としないタグ名のリストです。デフォルトは [ "input", "br", "meta", "img", "hr" ] です。
- CHARSET
- 文字コードを指定します。出力用言語がjstl11、jstl10のときに使用されます。
- EMBED_PATTERN
- プレゼンテーションデータ中に式を埋め込むためのパターンを指定します。
- INCDIRS
-
「
include:」ディレクティブで読み込むファイルを探すディレクトリを指定します。 デフォルトは [ "." ] つまりカレントディレクトリです。