Kwartz 3.0 Users' Guide

Makoto Kuwata <kwa(at)kuwata-lab.com>
last update: $Date: 2006-05-22 22:25:43 +0900 (Mon, 22 May 2006) $

Preface

This is the users' guide of Kwartz(*1), a template system which realized the concept of 'Independence of Presentation Logic'.

(*1)
Development of Kwartz had subsidized by Exploratory Software Project of IPA (Information-Technology Promotion Agency Japan).

Table of Contents



Introduction to Kwartz

What's Kwartz?

Kwartz(*2) is a template system which realized the concept of 'Independence of Presentation Logic'(IoPL). It means that Kwartz separates presentaion logics from both presentation data (typically HTML document) and business logics.

You know CSS (Cascading Style Sheet). CSS separates design from HTML file. In the same way, Kwartz separates presentation logics from HTML template. If you are familiar with CSS, you'll be also familiar with Kwartz.

The following figure show the relation of HTML, CSS, JavaScript, and Kwartz.

Figure1. Relation of HTML, CSS, JavaScript, and Kwartz.
relation of HTML, CSS, JavaScript, and Kwartz

Kwartz-ruby is an implemenation of Kwartz in Ruby. There is a plan to implement Kwartz in PHP or Java.

In the following, the word 'Kwartz' means the specification of the template system and the word 'Kwartz-ruby' means the implementation of it in Ruby language.

(*2)
'Kwartz' is pronounced like 'Quartz'.

Features Overview

Kwartz has the following features:

Separates presentation logic from presentation data.

Using template systems such as Smarty, Velocity, XMLC, amrita, etc, you can separate HTML design from business logic as a template. With Kwartz, you can separate presentation logic from a template. In other words, Kwartz divides a template into 'presentation data' and 'presentation logic'. You need not mix presentation logic into HTML files nor main program.

Very fast

Kwartz creates a script from a template (= presentation data and presentaion logic). All you have to do in main program is to call the output script. Because Kwartz doesn't use DOM trees or the like, it is both fast and light-weight.

Multi-languages support

Kwartz can create output scripts for Ruby(eRuby), PHP, JSP(JSTL 1.2 & 1.1). Presentation logics are written in each language(*3). This approach gives you the power of the target language fully. For example, you can write Ruby on Rails helper method (such as link_to, field_tag, and so on) directly in your template file.

Doesn't break HTML design at all

You must use directives like {foreach ...}{/foreach} in Smarty or #foreach(...) in Jakarta Velocity. These directives break the HTML design of template. Kwartz doesn't break HTML design because Kwartz uses id or title attributes for marking in an HTML template.

Able to handle any text file

Kwartz uses an original template parser; not using an HTML or XML parser, it is able to handle any type of text file (HTML, PostScript, CSV, and so on). This also means that Kwartz can handle non-well-formed XML files, as well as well-formed XML files. This is an advantage of Kwartz against Enhydra XMLC or amrita, which handle only XML/HTML files.

Auto-escape and Partial-escape

Kwartz can do sanitizing automatically. You don't need to write 'CGI.escapeHTML(var)' or 'htmlspecialchars($var)'. You are free to turn sanitizing on/off, as well specifying which parts of the template to sanitize.

(*3)
Previous version of Kwartz adopt original language and convert it to each target language(Ruby, PHP, JSTL, and so on). From Current version, it is required to write presentation logic in target language.

Simple Example

In Kwartz, a template is defined as both presentation data and presentation logic. They may be described in separate files.

This is an example of a presentation data file.

Presentation data file(example1.html):

<table>
  <tr id="list1">
    <td id="mark:item1">foo</td>
  </tr>
</table>

And the following is an example of presentation logic. In presentation logic, you can operate on elements which are marked in presentation data.

Presentation logic file(example1.plogic):
/* The element which is marked by 'id="list1"' */
#list1 {
  logic: {
    for member in @members
      _stag           # start tag
      _cont           # content
      _etag           # end tag
    end
  }
}

/* The element which is marked by 'id="mark:item1"' */
#item1 {
  /* replace the content with value of a variable 'member' */
  value: member;
}

(Don't forget the semicolon at the end of line especially for Ruby user!)

Kwartz generates eRuby script from the above files. This action is called 'compiling'.

how to compile eRuby script
$ kwartz -p example1.plogic example1.html > example1.rhtml

The following is the compiled eRuby script. Notice that id="mark:item1" is removed automatically while id="list1" is leaved.

generated eRuby script
<table>
<%     for member in @members %>
  <tr id="list1">
    <td><%= member %></td>
  </tr>
<%     end %>
</table>

Complex Example

Next is bordered table example which is a little complex than previous.

Presentation Data (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>

The following is the presentation logic file. In the presentation logic, you should detect whether odd or even line in the iteration.

Presentation Logic (example2.plogic):

/*
 * an element which is marked by 'id="mark:list"'
 *  - print value of a variable 'color' as bgcolor attribute value.
 */
#list {
  attrs:  "bgcolor" color;
  logic: {
    @members.each_with_index do |member, i|
      color = i % 2 == 0 ? '#FFCCCC' : '#CCCCFF';
      _stag    # start tag
      _cont    # content
      _etag    # end tag
    end
  }
}

/*
 * an element which is marked by 'id="mark:name"':
 *  - print value of member[:name] as content of the element.
 */
#name {
  value: member[:name];
}

/*
 * an element marked by 'id="mark:email"':
 *  - print value of member[:email] as contentn of the element. 
 *  - print "mailto:" and member[:email] as href attribute value.
 */
#email {
  value: member[:email];
  attrs: "href" "mailto:#{member[:email]}";
}

(Don't forget the semicolon at the end of line especially for Ruby user!)

You will find that there is no HTML tag in the presentation logic and no logic in the presentation data. That is to say, Kwartz can separate presentation logic from presentation data.

compilation
$ kwartz -p example2.plogic example2.html > example2.rhtml
output script
<table>
<%     @members.each_with_index do |member, i| %>
<%       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>

Other Examples of Presentation Logic

Kwartz enables you to write complex presentation logic natulally. This section shows some examples. See Presentation Pattern Catalog for details.

It is very important that tag/attribute names don't appear in presentation logic at all. This way, you don't need to change presentation logic files even if the tag/attribute names are changed in the presentation data.

Kwartz separates presentation logic from presentation data and main program.



Features Detail

RuleSet and Properties

Format of presentation logic in Kwartz is similar to CSS (Cascading Style Sheet).

The following rules are available in presesntation logic file. These are similar to CSS. If you are familiar with CSS, you'll be so with Kwartz.

stag: expr;
Replace start-tag by expression value.
etag: expr;
Replace end-tag by expression value.
elem: expr;
Replace elemnt by expression value.
cont: expr;
Replace content of element by expressin value.
value: expr;
Equivarent to cont: expr.
attrs: 'attrname' expr;
Replace attribute value by expression. The following is an example to specify some attributes.
#foo {
  attrs:  'href'  item[:url],
	  'id'    item[:id],
          'class' classname;
}
append: expr;
Append expression value to tail of tag. This is used especially to add 'checked="checked"', 'selected="selected"' into the form control tag.
#checkbox1 {
  append:  member[:age] > 18 ? ' checked="checked"' : '';
}
#select_options {
  append:  option[:value] == current_val ? ' selected="selected"' : '';
}
remove: 'attr1', 'attr2', 'attr3';
Remove the attributes from the element.
logic: { ... }
Logic of the element.

'stag:' and 'elem:' are useful especially for Ruby on Rails. The following is an examle to use Kwartz in Ruby on Rails.

presentation data (form1.html)
<form id="form">
  Name: <input type="text" id="member_name"><br>
  Birthday: <select id="member_birth">
              <option> - </option>
            </select><br>
 <input type="submit" id="submit">
</form>
presentation logic (form1.plogic)
#form {
  stag:  start_form_tag :action=>'new';
}
#member_name {
  elem:  text_field 'member', 'name';
}
#member_birth {
  elem:  date_select 'member', birth';
}
#submit {
  elem:  submit_to 'Submit';
}
compile
$ kwartz -p form1.plogic form1.html
<%= start_form_tag :action=>'new' %>
  Name: <%= text_field 'member', 'name' %><br>
  Birthday: <%= date_select 'member', birth' %><br>
 <%= submit_to 'Submit' %>
</form>

Directives

Presentation logic may be embedded into presentation data in Kwartz. You can choose to separate or not to sepearate presentation logic from presentation data.

The reason to provide both solutions (separate or not) is choosability. Some preferes to separate presentation logic from presentaion data, and others may prefere to mix them. Both approaches have own advantages and disadvantages. Thus it is the user who determine which solution to adopt. Kwartz provides both approaches and you can select which to use. Kwartz doesn't enforce you to adopt a solution.

To embed presentation logic into presentation data, use directives. Directive is a command to embed presentation logic into presentation data. In Kwartz, 'title' attributes(*4) are used to describe directives.

The following is an example to use directives.

Presentation Data(directive1.html):
<table>
  <tr title="for member in @members">
    <td title="value: member.name">foo</td>
    <td>
      <a href="mailto:<%= member.email %>"
         title="value: member.email">foo@mai.com</a>
    </td>
  </tr>
  <tr title="dummy:">
    <td>bar</td>
    <td><a href="mailto:bar@mail.org">bar@mail.org</a></td>
  </tr>
  <tr title="dummy:">
    <td>baz</td>
    <td><a href="mailto:baz@mail.net">baz@mail.net</a></td>
  </tr>
</table>
Compile:
$ kwartz -l eruby  directive1.html > directive1.rhtml
Output script:
<table>
<% for member in @members do %>
  <tr>
    <td><%= member.name %></td>
    <td>
      <a href="mailto:<%= member.email %>"><%= member.email %></a>
    </td>
  </tr>
<% end %>
</table>

If the first character of target attribute is a space, Kwartz recognize it as non-directive(*5).

presentation data (directive2.html)
<span title="value: expr1">foo</span>
<span title=" value: expr2">bar</span>
compile
$ kwartz directive2.html
<span><%= expr1 %></span>
<span title="value: expr2">bar</span>

Directives are different in each target language. For example, foreach loop is 'for item in list' in eRuby, 'foreach($list as $item)' in PHP, 'forEach(item in list)' in JSTL. See reference manual for details about directives.

(*4)
It is able to change attribute name by command-line option '--dattr=name' or configuration option PROPRERTY_DATTR.
(*5)
This spec may change in the future if I get have better idea.

Escape

Kwartz supports Automatic-escape and Partial-escape/unescape.

presentation Data (escape1.html):
<tr>
  <td id="mark:val1">foo</td>
  <td id="mark:val2">bar</td>
  <td id="mark:val3">baz</td>
</tr>
presentation logic (escape1.plogic)
#val1 {
  value: expr;
}
#val2 {
  Value: expr;
}
#val3 {
  VALUE: expr;
}
compile without '-e' option.
$ kwartz -p escape1.plogic escape1.html
<tr>
  <td><%= expr %></td>
  <td><%=h expr %></td>
  <td><%= expr %></td>
</tr>
comple with '-e' option.
$ kwartz -e -p escape1.plogic escape1.html
<tr>
  <td><%=h expr %></td>
  <td><%=h expr %></td>
  <td><%= expr %></td>
</tr>

In the same way, 'Stag:', 'Etag:', 'Elem:', 'Cont:', 'Attrs:', and 'Append:' properties are always escaped, 'STAG:', 'ETAG:', 'ELEM:', 'CONT:', 'ATTRS:', and 'APPEND:' properties are never escaped.

Escape function or method is different for each tareget language. 'h()' is used in eRuby and 'htmlspecialchars()' in PHP. JSTL prints escaped value in default.

Directives title="Value: expr", title="Attr: 'name' expr", and title="Append: expr" always escape expression value even when the command-line option '-e' is not specified.

Directives title="VALUE: expr:", title="ATTR: 'name' expr", and title="APPEND: expr" doesn't escape expression value even when the command-line option '-e' is specified.

Configuration option PROPERTY_ESCAPE in 'kwartz/config.rb' determines whether values are escaped or not in default. If this is true then Kwartz will escape values in default.


Multi-language

Kwartz-ruby now supports the following programming language.

Presentation logics must be described in each target language. It means that if you have wrote presentation logics in Ruby, they were not reusable for PHP project (but you can get full-power of Ruby in presentation logic).

The followings are examples of Ruby, PHP, JSP, and Perl.

table1.html
<html>
  <body>
  
    <table>
      <tr bgcolor="#CCCCFF" id="mark:row">
        <td id="mark:name">Foo</td>
        <td id="mark:mail">foo@mail.com</td>
      </tr>
      <tr bgcolor="#FFCCCC" id="dummy:row1">
        <td>Bar</td>
        <td>bar@mail.net</td>
      </tr>
      <tr bgcolor="#CCCCFF" id="dummy:row2">
        <td>Baz</td>
        <td>baz@mail.org</td>
      </tr>
    </table>

 </body>
</html>
table1.eruby.plogic
#row {
  attrs:  "bgcolor" color;
  logic: {
    @list.each_with_index do |user, i|
      color = i % 2 == 1 ? '#FFCCCC' : '#CCCCFF';
      _elem
    }
  }
}

#name {
  Value:  user[:name];
}

#mail {
  value:  user[:mail];
}
table1.php.plogic
#row {
  attrs:  "bgcolor" $color;
  logic: {
    $i = 0;
    foreach ($list as $user) {
      $color = ++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF';
      _elem();
    }
  }
}

#name {
  Value:  $user['name'];
}

#mail {
  value:  $user['mail'];
}
table1.jstl.plogic
#row {
  attrs:  "bgcolor" color;
  logic: {
    <c:forEach var="user" items="${list}" varStatus="loop">
      <c:set var="color" value="${loop.index % 2 == 0 ? '#FFCCCC' : '#CCCCFF'}"/>
      _elem
    </c:forEach>
  }
}

#name {
  Value:  user.name;
}

#mail {
  value:  user.mail;
}
table1.eperl.plogic
#row {
  attrs:  "bgcolor" $color;
  logic: {
    $i = 0;
    foreach ($user in @list) {
      $color = ++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF';
      _elem();
    }
  }
}

#name {
  Value:  $user{'name'};
}

#mail {
  value:  $user{'mail'};
}
compile
$ kwartz -l eruby -p table1.eruby.plogic table1.html > table1.rhtml
$ kwartz -l php   -p table1.php.plogic   table1.html > table1.php
$ kwartz -l jstl  -p table1.jstl.plogic  table1.html > table1.jsp
$ kwartz -l eperl -p table1.eperl.plogic table1.html > table1.iphtml
output script (table1.rhtml)
<html>
  <body>
  
    <table>
<%       @list.each_with_index do |user, i| %>
<%          color = i % 2 == 1 ? '#FFCCCC' : '#CCCCFF' %>
      <tr bgcolor="<%= color %>">
        <td><%=h user[:name] %></td>
        <td><%= user[:mail] %></td>
      </tr>
<%       end %>
    </table>

 </body>
</html>
output script (table1.php)
<html>
  <body>
  
    <table>
<?php     $i = 0; ?>
<?php     foreach ($list as $user) { ?>
<?php       $color = ++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'; ?>
      <tr bgcolor="<?php echo $color; ?>">
        <td><?php echo htmlspecialchars($user['name']); ?></td>
        <td><?php echo $user['mail']; ?></td>
      </tr>
<?php     } ?>
    </table>

 </body>
</html>
output script (JSTL 1.2)
<%@ taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<html>
  <body>
  
    <table>
    <c:forEach var="user" items="${list}" varStatus="loop">
      <c:set var="color" value="${loop.index % 2 == 0 ? '#FFCCCC' : '#CCCCFF'}"/>
      <tr bgcolor="${color}">
        <td>${user.name}</td>
        <td>${user.mail}</td>
      </tr>
    </c:forEach>
    </table>

 </body>
</html>
output script (ePerl)
<html>
  <body>
  
    <table>
<?     $i = 0; !>
<?     foreach ($user in @list) { !>
<?       $color = ++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'; !>
      <tr bgcolor="<?= $color !>">
        <td><?= encode_entities($user{'name'}) !></td>
        <td><?= $user{'mail'} !></td>
      </tr>
<?     } !>
    </table>

 </body>
</html>

Span Tag Deletion

Kwartz regards span tags which contain only directives as dummy tags and delete them automatically when command-line option '--delspan' is specified.

presentation data (delspan1.html)
<h1><span id="mark:title">title</span></h1>

Hello <span title="value: user">World</span>!
presentation logic (delspan1.plogic)
#title {
  value: title;
}
compile
$ kwartz -p delspan1.plogic --delspan delspan1.html
<h1><%= title %></h1>

Hello <%= user %>!

The span tags are not removed when they have other attributes.

presentation data (delspan2.html)
Hello <span title="value: user" style="color:black">World</span>!
compile
$ kwartz --delspan delspan2.html
Hello <span style="color:black"><%= user %></span>!

Import Presentation Logic File

'@imort "filename.plogic"' imports filename.plogic. This is useful to share common presentation logic in many files.

link_to.plogic
#link_to_new {
  elem:  start_link_to :action=>'new';
}
#link_to_show {
  elem:  start_link_to :action=>'show', :id=>@member;
}
#link_to_edit {
  elem:  start_link_to :action=>'edit', :id=>@member;
}
#link_to_list {
  elem:  start_link_to :action=>'list';
}
#link_to_destroy {
  stag:  start_link_to({:action=>'destroy', :id=>@member}, :confirm=>'Are you sure?');
}
show.html
<p>
 Name: <span id="mark:name">foo</span> <br>
 Email: <span id="mark:email">foo@mail.com</span> <br>
</p>
<a href="#" id="link_to_edit">Edit this member</a> |
<a href="#" id="link_to_new">Create new member</a> |
<a href="#" id="link_to_list">Return to list</a>
show.plogic
@import 'link_to.plogic';

#name {
  Value: @member.name;
}
#email {
  Value: @member.email;
}
compile
$ kwartz -p show.plogic show.html
<p>
 Name: <span><%=h @member.name %></span> <br>
 Email: <span><%=h @member.email %></span> <br>
</p>
<%= start_link_to :action=>'edit', :id=>@member %> |
<%= start_link_to :action=>'new' %> |
<%= start_link_to :action=>'list' %>

Import Elements in Other Files

Command-line option '-i filename,...' imports element definitions form other files.

form.html
<form>
 <div id="mark:form_content">
  Name: <input type="text"><br>
  Password: <input type="password"><br>
 </div>
 <input type="submit">
</form>
new.html
<form action="/new">
  <div id="mark:placeholder"></div>
  <input type="submit" value="Create">
</form>
new.plogic
/* use element which is defined other file */
#placeholder {
  logic: {
    _content(form_content)
  }
}
compile
$ kwartz -i form.html -p new.plogic new.html
<form action="/new">
  Name: <input type="text"><br>
  Password: <input type="password"><br>
  <input type="submit" value="Create">
</form>

Extract Element

Command option '-X name' extracts element marked as name and command option '-x name' extracts content of element.

show.html
<html>
 <body>
  <div id="mark:content">
   <h1>Show</h1>
   <p>Name: <span id="mark:name">foo</span></p>
   <p>Email: <span id="mark:email">foo@mail.com</span></p>
  </div>
 </body>
</html>
show.plogic
#name {
  value: user.name;
}
#email {
  value: user.email;
}
compile with '-X'
$ kwartz -X content -p show.plogic show.html
  <div>
   <h1>Show</h1>
   <p>Name: <span><%= user.name %></span></p>
   <p>Email: <span><%= user.email %></span></p>
  </div>
compile with '-x'
$ kwartz -x content -p show.plogic show.html
   <h1>Show</h1>
   <p>Name: <span><%= user.name %></span></p>
   <p>Email: <span><%= user.email %></span></p>

Print Statement

Print statement is available in 'logic:' property.

print-stmt.html
<ul>
  <li id="items">foo</li>
</ul>
print-stmt.eruby.plogic
#items {
  logic: {
    for item in list
      _stag
      print item
      _etag
    end
  }
}
compile
$ kwartz -l eruby -p print-stmt.eruby.plogic print-stmt.html
<ul>
<%     for item in list %>
  <li id="items"><%= item %></li>
<%     end %>
</ul>
print-stmt.php.plogic
#items {
  logic: {
    foreach ($list as $item) {
      _stag();
      print($item);
      _etag();
    }
  }
}
compile
$ kwartz -l php -p print-stmt.php.plogic print-stmt.html
<ul>
<?php     foreach ($list as $item) { ?>
  <li id="items"><?php echo $item; ?></li>
<?php     } ?>
</ul>
print-stmt.jstl.plogic
#items {
  logic: {
    <c:forEach var="item" items="${list}">
      _stag
      print item
      _etag
    </c:forEach>
  }
}
compile (JSTL 1.2)
$ kwartz -l jstl -p print-stmt.jstl.plogic print-stmt.html
<%@ 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="items">${item}</li>
    </c:forEach>
</ul>
compile (JSTL 1.1)
$ kwartz -l jstl -p print-stmt.jstl.plogic --jstl=1.1 print-stmt.html
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<ul>
    <c:forEach var="item" items="${list}">
  <li id="items"><c:out value="${item}"/></li>
    </c:forEach>
</ul>

It is recommended to use 'elem:', 'stag:', 'etag:', 'cont:', or 'value:' instead of print statement because they can escape or unescape exression value.


Add Code at Beginning/End of Document

'#DOCUMENT' is a special selector which represents the document. In '#DOCUMENT', properties 'begin:' and 'end:' are available to add codes at beginning/end of document.

document-test.html
<html>
 <body>hello</body>
</html>
document-test.plogic
#DOCUMENT {
  begin: {
    title = _context[:title]
    user  = _context[:user]
  }
  end: {
    print "<!--end-->\n"
  }
}
compile
$ kwartz -p document-test.plogic document-test.html
<%     title = _context[:title] %>
<%     user  = _context[:user] %>
<html>
 <body>hello</body>
</html>
<%= "<!--end-->\n" %>


Other Topics

Restrictions around presentation logic

There are several restrictions in presentation logic file.


Restrictions around presentation data

Kwartz parses presentation data file by regular expression pattern matching. It means that Kwartz doesn't use HTML parser nor XML parser for parsing presentation data. This approach enables Kwartz to handle any type of text file, and also brings the following restrictions to Kwartz.


Makefile and Rakefile

The followings are examples of Makefile, Rakefile, Rantfile, and Rookbook.

example of Makefile
.SUFFIXES:  .rhtml .html .plogic

ALL    = file1.rhtml file2.rhtml file3.rhtml
LAYOUT = layout.html

default:  $(ALL)

%.rhtml:  %.html %.plogic
	kwartz -l eruby -p $*.plogic $*.html > $@

file3.rhtml: file3.html file3.plogic $(LAYOUT)
	kwartz -p file3.plogic -L $(LAYOUT) file3.html > file3.rhtml
example of Rakefile for Rake
all    = ["file1.rhtml", "file2.rhtml", "file3.rhtml"]
layout = 'layout.html'

task :default => all

rule '.rhtml' => ['.html', '.plogic']           do |t|
  pdata, plogic = t.sources
  sh "kwartz -l eruby -p #{plogic} #{pdata} > #{t.name}"
end

file 'file3.rhtml' => ["file3.html", "file3.plogic", layout] do |t|
  pdata, plogic, layout = t.prerequisites
  sh "kwartz -p #{plogic} -L #{layout} #{pdata} > #{t.name}"
end
example of Rantfile for Rant
all    = ["file1.rhtml", "file2.rhtml", "file3.rhtml"]
layout = 'layout.html'

task :default => all

gen Rule, ".rhtml" => [".html", ".plogic"] do |t|
  pdata, plogic = t.prerequisites
  sys "kwartz -p #{plogic} #{pdata} > #{t.name}"
end

file "file3.rhtml" => ["file3.html", "file3.plogic", layout] do |t|
  pdata, plogic, layout = t.prerequisites
  sys "kwartz -p #{plogic} -L #{layout} #{pdata} > #{t.name}"
end
example of Rookbook for Rook
properties:
  - layout  :  layout.html

variables:
  - all     :  [ file1.rhtml, 'file2.rhtml', file3.rhtml ]
  - rook_product:  $(all)

recipes:

  - product:	*.rhtml
    ingreds:	[ $(1).html, $(1).plogic ]
    method: |
        pdata, plogic = @ingreds
	sys "kwartz -p #{plogic} #{pdata} > #{@product}"

  - product:	file3.rhtml
    ingres:	[ file3.html, file3.plogic, $(layout) ]
    method: |
        pdata, plogic, layout = @ingreds
	sys "kwartz- p #{plogic} -L $(layout) #{pdata} > #{@product}"

Use Kwartz as Library

If you want to use Kwartz library in your Ruby script, use Kwartz::Main class.

usage of Kwartz::Main class
require 'kwartz'
require 'kwartz/main'

argv = %w[-p hello.plogic -L layout.html hello.html]
main = Kwartz::Main.new(argv)
output = main.execute()
File.open('hello.rhtml', 'w') { |f| f.write(output) }

link_to() method in Ruby on Rails

link_to() method in Ruby on Rails is a little incompatible with Kwartz because you must specify link label in both presentation data and presentation logic. It's not DRY.

presentation data
<a href="#" id="mark:link_to_new">Create new recipe</a>
presentation logic
#link_to_new {
  elem:  link_to 'Create new recipe', :action=>'new';
}

It is recommended to include the following helper method in your 'app/helpers/application_helper.rb'.

module ApplicationHelper

  def start_link_to(options = {}, html_options = nil, *parameters_for_method_reference)
    s = link_to('', options, html_options, *parameters_for_method_reference)
    s.sub!(/<\/a>\z/, '')
  end
  alias anchor start_link_to

  def start_link_to_remote(options = {}, html_options = {})
    s = link_to_remote(options, html_options)
    s.sub!(/<\/a>\z/, '')
  end
  alias anchor_remote start_link_to_remote

end

The above methods prints only start tag. You don't need to write label twice.

presentation data
<a href="#" id="mark:link_to_new">Create new recipe</a>
presentation logic
#link_to_new {
  stag:  start_link_to :action=>'new';
}