Kwartzユーザーズガイド

Makoto Kuwata <kwa(at)kuwata-lab.com>
last update: $Date: 2005-03-07 08:15:41 +0900 (Mon, 07 Mar 2005) $

はじめに

このドキュメントは、テンプレートシステムKwartz(*1)のユーザーズガイドです。 Kwartzは、『プレゼンテーションロジックとプレゼンテーションデータの分離(Separation of Presentation Logic and Presentation Data, SoPL/PD)』という概念を実現したテンプレートシステムです。

(*1)
Kwartzの開発は、情報処理推進機構(IPA)による平成15年度未踏ソフトウェア創造事業の支援を受けました。

目次



Kwartzについて

Kwartzとは?

Kwartz(*2)とは、 『プレゼンテーションロジックとプレゼンテーションデータの分離(Separation of Presentation Logic and Presentaion Data(SoPL/PD)』という概念を実現したテンプレートシステムです。

Kwartz-rubyは、RubyによるKwartzの実装です。 このほか、PHPやJavaによる実装も予定されています。

以降の説明では、「Kwartz」という言葉はテンプレートシステムの仕様を説明するときに使用し、 「Kwartz-ruby」という言葉は特定の実装について説明するときに使用します。

(*2)
Kwartzは'Quartz'と同じように発音してください。

特徴

Kwartzには次のような特徴があります。

プレゼンテーションデータとプレゼンテーションロジックとが分離可能

通常のテンプレートシステムではテンプレートとメインプログラムとを分離します。 Kwartzでは更に、テンプレートをプレゼンテーションデータとプレゼンテーションロジックとに分離します。 これにより、プレゼンテーションロジックがHTMLの中に混じることも、またメインプログラムに紛れ込むこともありません。

高速な動作

Kwartzでは、テンプレート(プレゼンテーションデータとプレゼンテーションロジック)から出力用スクリプトを生成します。 これをあらかじめ行っておくため、実行時には出力用プログラムを呼び出すだけでよく、極めて高速に動作します。 またDOMツリーのような木構造を使わずに済むため、他のテンプレートシステムよりも高速です。

複数のプログラミング言語に対応

Kwartzは内部で独自の中間言語を採用することにより、様々なプログラミング言語から使用できるようになっています。 つまり、ひとつのHTMLテンプレートを様々な言語から使用することができるのです。 また使用する言語を変えたとしても、プレゼンテーション層は何も変更する必要がありません。 現在のところ、Ruby(eRuby)、PHP、JSP(JSTL 1.1&1.0)に対応しています。

HTMLテンプレートがSGML形式を崩さない

Kwartzでは、HTMLテンプレートにおけるマーキング(印付け)をid属性で行っています。 そのため、 SmartyJakarta Velocity のようにHTMLテンプレートのデザインを崩してしまうことがありません。

任意のテキストファイルで使用可能

Kwartzでは、専用の属性がついたタグのみを認識し、それ以外のタグはただのプレーンテキストとみなします。 またHTMLパーサーやXMLパーサーを使用せず、独自に解析を行っています。 そのため、Enhydra XMLCamrita のようにXMLやHTMLでしか使用できないということはなく、任意のテキストファイルで使用可能です。

自動サニタイズ機能をサポート

Kwartzでは、サニタイズを自動的に行うようにすることができます。 つまり、いちいち「CGI.escapeHTML(var)」や「htmlspecialchars($var)」と書く必要がありません。 またサニタイズ機能はオン/オフすることができます。 さらに、ある部分だけをサニタイズする/しないを細かく指定できます。


簡単な例

Kwartzは、テンプレートをプレゼンテーションデータとプレゼンテーションロジックとに分けて記述します。 ここではその例を示します。

まずプレゼンテーションデータの例です。

プレゼンテーションデータ(example1.html):

<table>
  <tr id="list">
    <td id="item">foo</td>
  </tr>
</table>

次はプレゼンテーションロジックの例です。 プレゼンテーションロジックでは、プレゼンテーションデータにつけた「目印」に対して操作を行います。

プレゼンテーションロジック(example1.plogic):

#item {            // id="item" がついたエレメント
  value: member;      // 内容を変数memberの値で置き換える
  remove: "id";       // id属性を取り除く
}

#list {            // id="list" がついたエレメント
  remove: "id";       // id属性を取り除く
  plogic: {           // プレゼンテーションロジックを定義する
    foreach (member in member_list) {
      @stag;          // タグ(start tag)
      @cont;          // 内容(content)
      @etag;          // 終了タグ(end tag)
    }
  }
}

Kwartzはこの2つから各言語(eRuby, PHP, JSTL1.1&1.0)用の出力用スクリプトを自動生成します。 これをコンパイルといいます。 コンパイルするにはコマンドラインで次のようにします。

### for eRuby
$ kwartz -l eruby  -p example1.plogic example1.html > example1.rhtml

### for PHP
$ kwartz -l php    -p example1.plogic example1.html > example1.php

### for JSTL 1.1
$ kwartz -l jstl11 -p example1.plogic example1.html > example1.jsp

### for JSTL 1.0
$ kwartz -l jstl10 -p example1.plogic example1.html > example1.jsp

以下は自動生成された出力用スクリプトです。

出力用スクリプト for eRuby (example1.rhtml):

<table>
<% for member in member_list do %>
  <tr>
    <td><%= member %></td>
  </tr>
<% end %>
</table>

出力用スクリプト for PHP (example1.php):

<table>
<?php foreach ($member_list as $member) { ?>
  <tr>
    <td><?php echo $member; ?></td>
  </tr>
<?php } ?>
</table>

出力用スクリプト for JSTL 1.1(*3)(example1.jsp):

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<table>
<c:forEach var="member" items="${member_list}">
  <tr>
    <td><c:out value="${member}" escapeXml="false"/></td>
  </tr>
</c:forEach>
</table>

出力用スクリプト for JSTL 1.0(example1.jsp):

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<table>
<c:forEach var="member" items="${member_list}">
  <tr>
    <td><c:out value="${member}" escapeXml="false"/></td>
  </tr>
</c:forEach>
</table>

またコンパイル時にコマンドオプション -e をつけると、サニタイズされた出力用スクリプトが生成されます。 サニタイズには、eRubyではCGI.escapeHTML()が、PHPではhtmlspecialchars()が、JSTLではescapeXml="false"なしの<c:out/>が使用されます。

これらの出力用スクリプトをメインプログラムから呼び出すと、Webページが出力されます。 呼び出し方は、各プログラミング言語によって異なります。

メインプログラム(Ruby):

## データを用意する
member_list = [ 'Oboro', 'Ominae', 'Jaquemonde' ]

## ERBを使って出力する
require 'erb'
require 'cgi'        # for sanitizing
str = File.open('example1.rhtml') { |f| f.read() }
str.untaint
trim_mode = 1
erb = ERB.new(str, $SAFE, trim_mode)
print erb.result(binding())

## またはERubyを使う方法
require 'eruby'
require 'cgi'        # for sanitizing
ERuby::import('example1.rhtml')

メインプログラム(PHP):

<?php
   // データを用意する
   $member_list = array('Oboro', 'Ominae', 'Jaquemonde');
   
   // 出力する
   include('example1.php');
 ?>

メインプログラム(JSTL):

public void doGet(HttpServletRequest request,
                  HttpServletResponse response)
                  throws ServletException, IOException {
   ...
   // データを用意する
   java.util.List member_list = new java.util.ArrayList();
   member_list.add("Oboro");
   member_list.add("Ominae");
   member_list.add("Jaquemonde");

   // 出力
   RequestDispatcher dispatcher = 
       request.getRequestDispatcher('example1.jsp');
   dispatcher.include(request, response);
   // または dispatcher.forward(request, response);
}

出力用プログラムを呼び出して実行すると、例えば次のようなWebページが生成されます。

<table>
  <tr>
    <td>Oboro</td>
  </tr>
  <tr>
    <td>Ominae</td>
  </tr>
  <tr>
    <td>Jaquemonde</td>
  </tr>
</table>
(*3)
コマンドラインオプションとして「--charset=CHARSET」をつけると、JSTL用出力スクリプトでは「<%@ page contentType="text/html; charset=CHARSET" %>」をつけてくれます。

複雑な例

もう少し複雑な例として、色つきのテーブルを示します。

プレゼンテーションデータは次のようになります。 マーキングは「id="name"」ではなく「id="mark:name"」としています。 こうするとid属性は自動的に削除されますので、プレゼンテーションロジックファイルでいちいち「remove: "id"」と書く必要がなくなります。

プレゼンテーションデータ(example2.html):

<table>
 <tr bgcolor="#CCCCFF" id="mark:list">
  <td id="mark:name">foo</td>
  <td>
   <a href="mailto:foo@mail.com" id="mark:email">foo@mail.com</a>
  </td>
 </tr>
</table>

次はプレゼンテーションロジックです。 プレゼンテーションロジックでは、繰り返しを行いながら、奇数行か偶数行かの判定を行っています。

プレゼンテーションロジック(example2.plogic):

// id="mark:list" がついたエレメント:
// bgcolor属性の値として変数colorを出力する。
// また繰り返しを行い、奇数行と偶数行で変数colorの値を変える。
#list {
  attr:  "bgcolor" color;
  plogic: {
    i = 0;
    foreach (member in member_list) {
      i += 1;
      color = i % 2 == 0 ? '#FFCCCC' : '#CCCCFF';
      @stag;
      @cont;
      @etag;
    }
  }
}

// id="mark:name" がついたエレメント:
// 内容として member['name'] の値を出力する。
#name {
  value: member['name'];
}

// id="mark:email" がついたエレメント:
// 内容として member['email'] の値を出力する。
// またhref属性は "mailto:" .+ member['email'] の値を出力する。
// (「.+」は文字列の連結を行う演算子)
#email {
  value: member['email'];
  attr:  "href" ("mailto:" .+ member['email']);
}

見ておわかりのように、プレゼンテーションロジックにはHTMLタグが一切入らず、またプレゼンテーションデータにはロジックが一切入っていません。 つまり、プレゼンテーションデータとプレゼンテーションロジックの分離が実現できていることになります。

なおインクリメント演算子(++)は使えませんので、ctr++ のように書くことはできません。

コンパイル:

### for eRuby
$ kwartz -l eruby  -p example2.plogic example2.html > example2.rhtml

### for PHP
$ kwartz -l php    -p example2.plogic example2.html > example2.php

### for JSTL 1.1
$ kwartz -l jstl11 -p example2.plogic example2.html > example2.jsp

### for JSTL 1.0
$ kwartz -l jstl10 -p example2.plogic example2.html > example2.jsp

出力用スクリプト:

### for eRuby
<table>
<% i = 0 %>
<% for member in member_list do %>
<%   i += 1 %>
<%   color = i % 2 == 0 ? "#FFCCCC" : "#CCCCFF" %>
 <tr bgcolor="<%= color %>">
  <td><%= member["name"] %></td>
  <td>
   <a href="<%= "mailto:" + member["email"] %>"><%= member["email"] %></a>
  </td>
 </tr>
<% end %>
</table>

### for PHP
<table>
<?php $i = 0; ?>
<?php foreach ($member_list as $member) { ?>
<?php   $i += 1; ?>
<?php   $color = $i % 2 == 0 ? "#FFCCCC" : "#CCCCFF"; ?>
 <tr bgcolor="<?php echo $color; ?>">
  <td><?php echo $member["name"]; ?></td>
  <td>
   <a href="<?php echo "mailto:" . $member["email"]; ?>"><?php echo $member["email"]; ?></a>
  </td>
 </tr>
<?php } ?>
</table>

### for JSTL
<table>
<c:set var="i" value="0"/>
<c:forEach var="member" items="${member_list}">
  <c:set var="i" value="${i + 1}"/>
  <c:set var="color" value="${i % 2 eq 0 ? '#FFCCCC' : '#CCCCFF'}"/>
 <tr bgcolor="<c:out value="${color}" escapeXml="false"/>">
  <td><c:out value="${member['name']}" escapeXml="false"/></td>
  <td>
   <a href="<c:out value="${fn:join('mailto:',member['email'])}" escapeXml="false"/>"><c:out value="${member['email']}" escapeXml="false"/></a>
  </td>
 </tr>
</c:forEach>
</table>

プレゼンテーションロジックの応用例

Kwartzでは、複雑なプレゼンテーションロジックが素直に記述できます。 ここではその例を示します。 なお『プレゼンテーションパターンカタログ』もご覧ください。

ここで重要なのは、プレゼンテーションロジックにはタグ名や属性名が一切出てきていないという点です。 プレゼンテーションデータのほうでどんなにタグを変更したとしても、プレゼンテーションロジックはまったく変更する必要はありません。

つまり、プレゼンテーションデータとプレゼンテーションロジックとが完全に分離されているわけです。



ディレクティブ

Kwartzでは、プレゼンテーションデータの中にプレゼンテーションロジックを埋め込むこともできます。 つまり、両者を分離することも、一体化することもできるわけです。

プレゼンテーションロジックをプレゼンテーションデータの中に埋め込むには、ディレクティブを用います。 ディレクティブとは、プレゼンテーションデータの中にプレゼンテーションロジックを埋め込むための命令です。 Kwartzでは、id属性とkw:d属性を用いてディレクティブを記述します。

次はディレクティブを使った例です:

プレゼンテーションデータ(example3.html):

<table>
  <tr id="foreach:member=member_list">
    <td id="value:member['name']">foo</td>
    <td><a href="mailto:@{member['email']}@">
         @{member['email']}@</a></td>
  </tr>
  <tr id="dummy:d1">
    <td>bar</td>
    <td><a href="mailto:bar@mail.org">bar@mail.org</a></td>
  </tr>
  <tr id="dummy:d2">
    <td>baz</td>
    <td><a href="mailto:baz@mail.net">baz@mail.net</a></td>
  </tr>
</table>

コンパイル:

### for eRuby
$ kwartz -l eruby   example3.html > example3.rhtml

### for PHP
$ kwartz -l php     example3.html > example3.php

### for JSTL1.1
$ kwartz -l jstl11  example3.html > example3.jsp

出力用スクリプト:

### for eRuby
<table>
<% for member in member_list do %>
  <tr>
    <td><%= member["name"] %></td>
    <td><a href="mailto:<%= member["email"] %>">
         <%= member["email"] %></a></td>
  </tr>
<% end %>
</table>

### for PHP
<table>
<?php foreach ($member_list as $member) { ?>
  <tr>
    <td><?php echo $member["name"]; ?></td>
    <td><a href="mailto:<?php echo $member["email"]; ?>">
         <?php echo $member["email"]; ?></a></td>
  </tr>
<?php } ?>
</table>

### for JSTL
<table>
<c:forEach var="member" items="${member_list}">
  <tr>
    <td><c:out value="${member['name']}" escapeXml="false"/></td>
    <td><a href="mailto:<c:out value="${member['email']}" escapeXml="false"/>">
         <c:out value="${member['email']}" escapeXml="false"/></a></td>
  </tr>
</c:forEach>
</table>

このほか、条件分岐を行うディレクティブなども用意されています。 詳細はリファレンスマニュアルをご覧ください。

(*4)
このパターンは設定ファイルの定数EMBED_PATTERNで変更できます。

サニタイズ

Kwartzでは、自動でサニタイズを行うことができます。 またある部分だけをサニタイズする/しないを選択することもできます。

自動サニタイズ

コマンドラインオプション -e をつけると、出力スクリプトをサニタイズします。 サニタイズでは、eRubyではCGI.escapeHTML()が、ERBではh()が、PHPではhtmlspecialchars()が、JSTLではescapeXml="false"なしの<c:out>がそれぞれ使用されます。

プレゼンテーションデータ:

<tr bgcolor="@{color}@">
  <td id="value:str">foo</td>
</tr>

コンパイル:

### for eRuby
$ kwartz -e -l eruby  sanitize1.html > sanitize1.rhtml
	
### for ERB
$ kwartz -e -l erb    sanitize1.html > sanitize1.rhtml
	
### for PHP
$ kwartz -e -l php    sanitize1.html > sanitize1.php
	
### for JSTL 1.1
$ kwartz -e -l jstl11 sanitize1.html > sanitize1.jsp

出力用スクリプト:

### for eRuby
<tr bgcolor="<%= CGI::escapeHTML((color).to_s) %>">
  <td><%= CGI::escapeHTML((str).to_s) %></td>
</tr>

### for ERB
<tr bgcolor="<%=h(color)%>">
  <td><%=h(str)%></td>
</tr>

### for PHP
<tr bgcolor="<?php echo htmlspecialchars($color); ?>">
  <td><?php echo htmlspecialchars($str); ?></td>
</tr>

### for JSTL
<tr bgcolor="<c:out value="${color}"/>">
  <td><c:out value="${str}"/></td>
</tr>

式が文字列や数値のような定数の場合は、サニタイズされません。 また「flag ? 'checked' : ''」のような条件演算子では、flagの値にかかわらず文字列定数が出力されますので、これもサニタイズされません。


部分サニタイズ

関数E(expr)は、コマンドラインオプションに関わらず式exprをサニタイズします。 また関数X(expr)は、コマンドラインオプションに関わらず式exprをサニタイズしません。

プレゼンテーションデータ:

<table>
 <tr bgcolor="@{X(color)}@">
   <td id="value:E(str)">foo</td>
 </tr>
</table>

コンパイル:

### for eRuby
$ kwartz -e -l eruby  sanitize1.html > sanitize1.rhtml
	
### for ERB
$ kwartz -e -l erb    sanitize1.html > sanitize1.rhtml
	
### for PHP
$ kwartz -e -l php    sanitize1.html > sanitize1.php
	
### for JSTL 1.1
$ kwartz -e -l jstl11 sanitize1.html > sanitize1.jsp

出力用スクリプト:

### for eRuby
<table>
 <tr bgcolor="<%= color %>">
   <td><%= CGI::escapeHTML((str).to_s) %></td>
 </tr>
</table>

### for ERB
<table>
 <tr bgcolor="<%= color %>">
   <td><%=h(str)%></td>
 </tr>
</table>

### for PHP
<table>
 <tr bgcolor="<?php echo $color; ?>">
   <td><?php echo htmlspecialchars($str); ?></td>
 </tr>
</table>

### for JSTL
<table>
 <tr bgcolor="<c:out value="${color}" escapeXml="false"/>">
   <td><c:out value="${str}"/></td>
 </tr>
</table>

またコマンドラインオプションに関係なく、「id="Value:expr"」や「id="Attr:name=expr)"」は式exprを必ずサニタイズします。 逆に、「id="VALUE:expr"」や「id="ATTR:name=expr"」は式exprを必ずサニタイズしません。 これらはそれぞれ、「id="value:E(expr)"」や「id="attr:name=X(expr)"」と同じです。


サニタイズの設定

kwartz/config.rbはKwartz-rubyの動作を設定しているファイルです。 デフォルトでサニタイズを行うように設定するには、この中で定数ESCAPEの値をtrueに変更します。



その他の話題

制限事項

Kwartzでは、HTMLパーサやXMLパーサを用いず、正規表現によるパターンマッチでHTMLファイルを解析しています。 そのため、HTMLではないテキストファイルでも利用できるという利点がありますが、次のような制限事項もあります。


グローバル変数とローカル変数

Kwartzには、プレゼンテーションデータ/ロジックファイルを分析し、変数を調査する機能があります。

Kwartzでは、メインプログラムで設定されて出力用スクリプトに渡される変数をグローバル変数、 テンプレートの中でだけ使用される変数をローカル変数と呼んでいます。 Kwartzは、変数がグローバルかローカルかを調べて報告する機能があります。

次の例をご覧ください。

プレゼンテーションデータ(analyze.html):

<span kw:d="value:title">Analyzer Example</span>
<dl id="mark:items">
 <dt kw:d="value:ctr"></dt>
 <dd kw:d="value:item">Foo</dd>
</dl>

プレゼンテーションロジック(analyze.plogic):

#items {
  plogic: {
    @stag;
    ctr = 0;
    foreach (item in list) {
      ctr += 1;
      @cont;
    }
    @etag;
  }
}

この例では4つの変数があります。 このうち、itemctrはテンプレート中でだけ使われるのでローカル変数、 titlelistはメインプログラムで設定されて出力用スクリプトに渡されるのでグローバル変数です。

kwartzをコマンドランオプション -a analyze をつけて起動すると、グローバル変数とローカル変数を報告してくれます。

実行例:

$ kwartz -a analyze -p analyze.plogic analyze.html
Global: title list
Local:  ctr item

ローカル変数の名前を変更する

RubyやPHPでは、メインプログラムで使用している変数名と、テンプレートのローカル変数名とが一致した場合、 ローカル変数名を変更することでメインプログラムの動作に影響を与えてしまうという問題があります。 これに対処するため、Kwartzではローカル変数名を自動的に変更する機能があります。

コンパイル時にコマンドラインオプション「--rename」を指定すると、 ローカル変数名の頭に「_をつけます。

前の節で使用したanalyze.htmlとanalyze.plogicを使ってみます。

実行例:

$ kwartz -l eruby  -p analyze.plogic --rename analyze.html
$ kwartz -l php    -p analyze.plogic --rename analyze.html
$ kwartz -l jstl11 -p analyze.plogic --rename analyze.html

出力用スクリプト:

### for eRuby
<%= title %>
<dl>
<% _ctr = 0 %>
<% for _item in list do %>
<%   _ctr += 1 %>
 <dt><%= _ctr %></dt>
 <dd><%= _item %></dd>
<% end %>
</dl>

### for PHP
<?php echo $title; ?>
<dl>
<?php $_ctr = 0; ?>
<?php foreach ($list as $_item) { ?>
<?php   $_ctr += 1; ?>
 <dt><?php echo $_ctr; ?></dt>
 <dd><?php echo $_item; ?></dd>
<?php } ?>
</dl>

### for JSTL
<c:out value="${title}" escapeXml="false"/>
<dl>
<c:set var="_ctr" value="0"/>
<c:forEach var="_item" items="${list}">
  <c:set var="_ctr" value="${_ctr + 1}"/>
 <dt><c:out value="${_ctr}" escapeXml="false"/></dt>
 <dd><c:out value="${_item}" escapeXml="false"/></dd>
</c:forEach>
</dl>

なお設定ファイルの定数RENAMEで、デフォルトでローカル変数名を変更する・しないを設定できます。


spanタグの削除

Kwartzでは、ディレクティブしか含まないようなspanタグは、ダミータグとみなされて自動的に削除されます。

プレゼンテーションデータ:

<h1><span id="mark:title">title</span></h1>

Hello <span id="value:user">World</span>!

プレゼンテーションロジック:

#title {
  value: title;
}

出力用スクリプト(for eRuby):

<h1><%= title %></h1>

Hello <%= user %>!

spanタグが他の属性を含んでいた場合は、削除されません。

プレゼンテーションデータ:

<h1><span id="mark:title" class="title">title</span></h1>

Hello <span kw:d="value:user" style="color:black">World</span>!

出力用スクリプト(for eRuby):

<h1><span class="title"><%= title %></span></h1>

Hello <span style="color:black"><%= user %></span>!

開始タグに式の値を追加する

<input type="..." checked>」のようにする場合は、次のようにします。

プレゼンテーションデータ:

<input type="checkbox" name="foo" value="Y" id="foo" />

プレゼンテーションロジック:

#foo {
  append: flag ? ' checked' : '';
}

出力用スクリプト:

### for eRuby
<input type="checkbox" name="foo" value="Y" id="foo"<%= flag ? " checked" : "" %> />

### for PHP
<input type="checkbox" name="foo" value="Y" id="foo"<?php echo $flag ? " 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" %>
<input type="checkbox" name="foo" value="Y" id="foo"<c:out value="${flag ? ' checked' : ''}" escapeXml="false"/> />

### for JSTL 1.0
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<c:choose><c:when test="${flag}">
<input type="checkbox" name="foo" value="Y" id="foo" checked />
</c:when><c:otherwise>
<input type="checkbox" name="foo" value="Y" id="foo" />
</c:otherwise></c:choose>

ディレクティブ id="append:expr" でも同じことができます。

プレゼンテーションデータ:

<input type="checkbox" name="foo" value="Y" id="append:flag?' checked':''" />

またchecked="checked"selected="selected"を簡単に出力するための関数を用意しています。 「C(expr)」「S(expr)」「D(expr)」は式exprが真だった場合に、 それぞれ「 checked="checked"」「 selected="selected"」「 disabled="disabled"」を出力します。

プレゼンテーションデータ:

<input type="checkbox" name="foo" value="Y" id="foo" />

プレゼンテーションロジック:

#foo {
  append: C(foo == 100);
}

出力用スクリプト:

### for eRuby
<input type="checkbox" name="foo" value="Y" id="foo"<%= foo == 100 ? " checked=\"checked\"" : "" %> />

### for PHP
<input type="checkbox" name="foo" value="Y" id="foo"<?php echo $foo == 100 ? " checked=\"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" %>
<input type="checkbox" name="foo" value="Y" id="foo"<c:out value="${foo eq 100 ? ' checked="checked"' : ''}" escapeXml="false"/> />

### for JSTL 1.0
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<c:choose><c:when test="${foo eq 100}">
<input type="checkbox" name="foo" value="Y" id="foo" checked="checked" />
</c:when><c:otherwise>
<input type="checkbox" name="foo" value="Y" id="foo" />
</c:otherwise></c:choose>

プレゼンテーションロジックをターゲット言語で記述する

行が「<%」または「<?」で始まる場合、そこから行末まではそのまま出力されます。 これにより、プレゼンテーションロジックをRubyやPHPやJavaで直接記述することができます。

プレゼンテーションロジック:

#list {
  plogic: {
    @stag;
    <% ENV.each { |name, value| %>
      @cont;
    <% } %>
    @etag;
  }
}

<%」または「<?」から行末までをraw-codeといいます。 raw-codeは文(statement)であり、式(expression)ではありません。 そのため、「plogic:」部に書くことはできますが「value:」部や「attr:」部に書くことはできません。