Kwartz Reference Manual

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

Preface

This document is the Kwartz Reference Manual. Presentation language (PL), directives, command-line options, and configuration option are described in this document.

Table of Contents



PL - Presentation Language

PL is a language which is used to describe presentation logic in Kwartz. This section shows how to write in PL.

Comments

Characters following '//' in a line is a comment.

// comment

Strings

"..." or '...' represents a string literal. The former can contain special characters: line feed (\n), carriage return (\r) and tab (\t).

'foo bar'         // String
"foo bar\n"       // String which contains a line feed character

Booleans and Null

The keywords true, false, null are available in expressions.

flag = obj == null ? true : false;

true, false and null are translated to the proper keywords in each language.

Translation of true, false and null
Language name true false null
PHP TRUE FALSE NULL
eRuby true false nil
JSP(JSTL) true false null

Variables

A varaible starts with alphabetic character or '_' and is followed by alphanumerics or '_'.

You need not declare variables nor specify its type(*1).

(*1)
Because of this feature, it is very difficult to translate PL program into "static languages" such as Java.

Operators

There are several operators in Kwartz. Comparison operators are available for numbers and strings(*2).

Operators
Comparison operators == != < <= > >=
Logical operators && || !
Arithmetic operators + - * / %
String Concatenation operators .+
Conditional operators ?:

String concatenation operator ('.+') is converted into '+' in eRuby, '.' in PHP, a function 'fn:join()' in JSTL1.1. There is no concatenation operator in JSTL1.0, so Kwartz converts it into a little tricky code.

PL Program (PL):

filename = basename .+ '.plogic';

Output Script:

### 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'}"/>

Conditional Operator is available in eRuby, PHP, and JSTL1.1. However, it is not available in JSTL1.0. Therefore, conditional operators will be translated to if statements in JSTL1.0.

PL Program:

color = ctr % 2 == 0 ? '#FFCCCC' : '#CCCCFF';

Output Script:

### 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)
It is very difficult to translate PL program into Perl program, because Perl have different operators for numbers and strings ('==' vs 'eq', '!=' vs 'ne', ...).

Printing

print(...); is print statement. Any expression can be in arguments.

PL Program:

print('foo', bar, "baz\n");    // print a string and the value of a variable

Output Script:

### for eRuby
foo<%= bar %>baz

### for PHP
foo<?php echo $bar; ?>baz

### for JSTL
foo<c:out value="${bar}" escapeXml="false"/>baz

When you enable auto-sanitizing, the output scripts will be one of the following:

### 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

If conditional operator returns constant string or number, sanitizing will be off even when using auto-sanitizing.

PL Program:

// Sanitized.
print("<option ", condition ? var1 : var2, ">\n");
// Not sanitized.
print("<option ", condition ? 'selected' : '', ">\n");

Output Script:

### 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"/>>

Assignment

Assignment statement is such as var = 100;. Also '+=', '-=', '*=', '/=', '%=' and '+=' are allowed.

PL Program:

name = 'Foo';		// assign a string
count += 1;		// increment the value of the variable
str .+= '.txt';		// append a string

Output Script:

### 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'}"/>

Arrays and Hashes

You can reference an array element as arr[expr]. You can reference a hash element in the same way.(*3).

In JSTL, assignment into an array element or a hash element is not available.

PL Program:

list[n] = 10;           // assign into n-th element of the array
print(list[i], "\n");     // print  i-th element of the array
hash['key'] = 'foo';    // assign into a hash element
print(hash['key'], "\n"); // print a hash element

Output Script:

### 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"]; ?>

You can reference a hash by 'hash[:key]'. 'key' must be a string which contains only alphpanumerics and '_'.

'hash[:key]' will be translated according to target programming language:

Translation of 'hash[:key]'
Target language Result of translation
eRuby hash[:key]
PHP $hash['key']
JSTL hash['key']

PL Program:

print(hash[:key]);

Output Script:

### for eRuby
<%= hash[:key] %>

### for PHP
<?php echo $hash['key']; ?>

### for JSTL
<c:out value="${hash['key']}" escapeXml="false"/>
(*3)
Operators for arrays and hashes are the same, therefore it is difficult to support a language, say Perl, which use different operators for arrays and hashes.

Properties & Methods

You can reference a property of an object as 'object->property'. You can also call a method with arguments such as 'object->method(arg1, arg2, ..)'. Translation of method call into JSTL will raise an error because JSTL's Expression Language doesn't support method call.

PL Program:

// property
user.name = 'Foo';
print(user.name, "\n");

Output Script:

### 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 Program:

// method call
print(user.method(10, 20));

Output Script:

### for eRuby
<%= user.method(10, 20) %>

### for PHP
<?php echo $user->method(10, 20); ?>

There is no way to create a new object or define a new class in PL. These tasks must be done in the main program.


Iteration

foreach(loopvar in list) { ... } represents a foreach iteration. Items in the list is assigned into the variable loopvar each time through the iteration.

PL Program:

foreach(item in list) {
  print(item, "\n");
}

Output Script:

### 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>

You can also use a while statment. Kwartz will raise an error if you try to translate a while statement into a JSTL script, because there is no JSTL tag which is equivalent to the while statment.

PL Program:

i = 0;
while(i < length) {
  i += 1;
  print(list[i]);
}

Output Script:

### 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 } ?>

for-statements (like in C or Java) are not available.


Conditional Branching

'if(condition) { ... } else if(condition) { ... } else { ... }' represents a conditional branch.

PL Program:

if (val > 0) {
  print ("* value is positive.\n");
} else if (val < 0) {
  print ("* value is negative.\n");
} else {
  print ("* value is zero.\n");
}

Output Script:

### 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>

Functions

The following functions are available in PL.

E(expr)
Sanitizes(escapes) the expression expr. Using this function sanitizes even when the command-line option for sanitizing is not specified.
X(expr)
Don't sanitize expression expr, even when the command-line option for sanitizing is specified.
C(expression)
Equivarent to expression ? ' checked="checked"' : ''.
S(expression)
Equivarent to expression ? ' selected="selected"' : ''.
D(expression)
Equivarent to expression ? ' disabled="disabled"' : ''.
list_new()
Create a new list.
list_length(list)
Return the length of the list.
hash_new()
Create a new hash.
hash_keys(hash)
Return a list which contains all keys of the hash.
str_length(string)
Return the length of the string.
str_tolower(string)
Make a string to lowercase and return it.
str_toupper(string)
Make a string to uppercase an return it.
str_trim(string)
Strip whitespace from the beginning and end of a string and return it.
str_index(string, char)
Return the first positin a char occurs in a string.

JSTL1.0 doesn't support any function, so you cannot use these function in JSTL1.0 (except E() and X()). JSTL1.1 supports some functions but it is limited. In fact, list_new(), hash_new(), and hash_keys() are not supported.

Functions eRuby PHP 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) -

All functions except above are printed "as is" when translating into PHP or eRuby script. Translating into JSTL script will be error because Exrepssion Language of JSTL doesn't support user-defined functions.

Functions E() and X() are intended to be used as arguments of print statement. You shouldn't use them in other place.


Empty

'empty' is a keyword used to check whether a value is either null or an empty string. It can be placed only at the right-side of the operators '==' and '!='.

PL Program:

if (str1 == empty) {
  print("str1 is empty.\n");
} else if (str2 != empty) {
  print("str2 is not empty.\n");
}

Output Script:

### 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>

Element declaration

Element declaration is description to manipulate elements marked by 'id="name"' or 'id="mark:name"', for example, delete attributes or change presentation logic. In Kwartz, presentation logic file is described as a set of element declarations.

Element declaration starts with '#name' and is followed by some declaration parts.

value: expression;
Replace content of the element by value of expression.
attr: "attr1" expr1 , "attr2" expr2 , ... ;
Replace value of attribute attr by value of expr.
remove: "attr1" , "attr2" , ... ;
Remove attribute attr.
append: expr1 , expr2 , ... ;
Append expression expr at the end of start tag. This is useful for appending checked or selected in <input> tag or <option> tag.
tagname: expression;
Replace tag name by value of expression. This may be useful for Struts or JSF.
plogic: { ... }
Change the presentation logic of the element. @stag, @cont, and @etag are available in { ... }. These represents start tag, content, end tag of the element respectively. And @element(other) is also available which represents other element and expand it.

Presentation Data:

<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>

Presentation Logic:

#foo {
  value:  item;
  attr:   "class" klass;
  plogic: {
    foreach (item in list) {
      @stag;
      @cont;
      @etag;
    }
  }
}
#chkbox {
  remove:  "checked";
  append:  flag ? " checked" : "";
  tagname: "html:text";
}

Output Script:

### 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 declaration

#DOCUMENT { ... } is a special element declaration for document. It represents document information and takes the following declaration parts.

begin: { ... }
Represents PL code which is added at the beginning of the output script.
end: { ... }
Represents PL code which is added at the end of the output script.
require: "filename1" , "filename2", ... ;
Load presentation logic file.
global: varname1 , varname2 , ... ;
List of global variables. Currently this part have no means but will be used in future release.
local: varname1 , varname2 , ... ;
List of local variables. Currently this part have no means but will be used in future release.

Presentation data:

<ul id="mark:list">
  <li id="value:item">foo</li>
</ul>

PL Program:

#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;
  }
}

Output script:

### 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. -->

Raw-code

Code in the target program language can be in the PL program. If Kwartz find a line starting with '<%' or '<?', Kwartz prints the string from '<%' or '<?' to the end of line directly.

The following is an example which includes PHP code.

PL Program:

<?php foreach($hash as $key => $value) { ?>
print("key=", key, " value=", value, "\n");
<?php } ?>

Output Script:

### for PHP
<?php foreach($hash as $key => $value) { ?>
key=<?php echo $key; ?> value=<?php echo $value; ?>
<?php } ?>

Raw-code can be in 'plogic:' part of element declaration, or 'begin:'/'end:' part of document declaration. This means that you can write presentation logics in target language.

Presentation Logic:

#foo {
  plogic: {
    @stag;
    <% hash.each do |key, value| %>
      @cont;
    <% end %>
    @etag;
  }
}

Raw-cde cannot be in 'value:' or 'attr:' part of element declaration, because raw-code is statement and not expression.

You should remember that writing a raw-code takes portability away.


Global and Local Variables

In Kwartz, variables are called Global variables if they are set in the main program and are passed to output script. Variables are called Local variables if they are used only in the template.

Assume the following presentation data and presentation logic:

Presentation data (analyze.html) :

<table>
  <caption id="value:title">Sample</caption>
  <tr id="mark:items" bgcolor="@{color}@">
    <td id="value:item">Foo</td>
  </tr>
</table>

Presentation logic (analyze.plogic) :

#items {
  plogic: {
    ctr = 0;
    foreach (item in list) {
      ctr += 1;
      color = ctr%2 == 0 ? '#FFCCCC' : '#CCCCFF';
      @stag;
      @cont;
      @etag;
    }
  }
}

There are several variables. They are classified as follows:

Global variables
The variables 'title' and 'list' need to be set in the main program and be passed to template. These variables are called 'Global variables' in Kwartz.
Local variables
The variables 'item', 'ctr', and 'color' are used only in the template. These variables are called 'Local variables' in Kwartz.

Invoking Kwartz with the command-line option '-a analyze' analyzes the template and reports global/local variables.

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

Kwartz detemines whether variables are global/local according to the following rule:

Kwartz reports warnings if global variables appears in the lefthand-side of assignments or are used as loop variables in foreach statements. Because the role of template system is to display global variables, templates should not change or modify global variables.

Analyzing templates and reporting global/local variables is very useful, especially when the presentation data/logic is large and complex. It also helps you to find typos of variable names.


Features Under Consideration

The following features are not implemented. They may be implemented in the future release (or not).



Directives

What is a Directive?

Kwartz allows presentation logic to be embedded in presentation data. Commands for that purpose are called 'directives'.

'Directives' is a set of commands to embed presentation logic into presentation data. Kwartz uses the id attribute and the kw:d attribute to embed directives in presentation data. Kw:d is an original attribute of Kwartz, but the ability of id and kw:d attributes are equivalent for Kwartz. Marking (id="name" or id="mark:name") is also a directive.

You may have a question: If it is the most important feature for Kwartz that separates presentation logic from presentation data, why does Kwartz allow me to embed presentation logic into presentation data?

The answer is choosability - to make it possible for developers to choose either approach. In other words, to increase options of development styles. Kwartz doesn't force you to use one approach. Separate presentation logic and presentation data if you like to separate them, or mix them if you like.

You may wonder whether Kwartz becomes an ordinary template system if presentation logic is embedded into presentation data. But Kwartz has the following merits compared to other template systems;


Marking

The directive 'id="name"' or 'id="mark:name"' marks an element with a name name. This is called 'marking'.

The difference between 'id="name"' and 'id="mark:name"' is that the former is left in but the latter is removed when compiling. kw:d attributes are always removed.

Presentation Data:

<div id="foo">foo</div>
<div id="mark:bar">bar</div>

Output Script:

### 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>

Printing Values of Expressions

'@{expression}@' is a directive which prints the value of an expression. This pattern is changeable with a constant EMBED_PATTERN in configuration file (kwartz/config.rb).

Presentation Data:

Hello @{user.name}@!

Output Program:

### for eRuby
Hello <%= user.name %>!

### for PHP
Hello <?php echo $user->name; ?>!

### for JSTL
Hello <c:out value="${user.name}" escapeXml="false"/>!

Expressions are sanitized if you specified the command-line option '-e' when compiling templates. Notice that all expressions except string and numbers constants are sanitized.

Output Program (with command-line option -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}"/>!

Using the functions E() or X(), you can toggle sanitizing on/off for each expression. E(expr) means that the expression expr is sanitized and X(expr) means that expr is not sanitized. These are not effected by the command-line option '-e'.

Presentation Data:

With sanitizing:    @{E(var)}@!
Without sanitizing: @{X(var)}@!

Output Program:

### 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"/>!

. .


Printing value of expression 2

'id="value:expression"' is a directive to print the value of expression instead of the content. It is more suitable for HTML design than '@{expression}@' because it allows for the use of dummy data.

Presentation Data:

<li id="value:hash['name']">foo</li>

Output Program:

### 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"' sanitizes the expression. 'id="VALUE:expr"' un-sanitizes the expression. These are equal to 'id="value:E(expr)"' and 'id="value:X(expr)"'.


Attribute Values

'id="attr:name=value"' (or 'id="attr:name:value"') is a directive to set an attribute value. It overwrites the existing value if attribute name is already set.

In the following example, attribute 'class' has the dummy value 'odd', and the actual value is derived from the variable 'klass'.

Presentation Data:

<tr class="odd" id="attr:class=klass">
  <td>foo</td>
</tr>

Output Program:

### 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"' sanitizes the value. 'id="ATTR:name=value"' un-sanitizes the value. These are equal to 'id="attr:name=E(value)"' and 'id="attr:name=X(value)"'.

Separating with ';', you can have several 'attr:name=value' directives in one id attribute. You can enumerate other attributes this way as well.

Presentation Data:

<font id="if:message!=empty;attr:class=klass;attr:bgcolor=color">
 @{message}@
</font>

Output Script:

### 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>

Appending Attribute Expression

'id="append:expression"' is a directive to append expression into a tag. This is useful to output '<input ... checked />' or '<option ... selected></option>'.

Presentation Data:

<option name="lang" value="ruby"
       id="append:lang=='ruby'?' selected':''">Ruby</option>
<input type="radio" name="gender" value="M"
       id="append:gender=='M'?' checked':''">

Output Script:

### 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>

A function to output 'checked="checked"', 'selected="selected"' and 'disabled="disabled"' easily for HTML/XHTML is available in Kwartz. C(expr), S(expr), and D(expr) print ' checked="checked"', ' selected="selected"' and ' disabled="disabled"' respectively when expression expr is true.

Presentation Data:

<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

Output Script:

### 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

Assignment

'id="set:var=value"' is a directive for assigning values into variables. Other than '=', '+=', '-=', '*=', '/=', '.=' are also available.

Presentation Data:

<dt id="set:var=value">foo</dt>
<dd id="set:count+=1">123</dd>

Output Program:

### 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>

Conditional Branching

'id="if:expression"' is a directive for conditional branching. 'else' and 'elseif' are also available.

Presentation Data:

<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>

Output Program:

### 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>

If using 'elseif' or 'else' directives, don't insert empty lines just before.


Iteration (foreach)

'id="foreach:loopvar=list)"' (or 'id="foreach:loopvar:list)"') is a directive for iteration, assigning each value in the array into a variable each time through the loop.

Presentation Data:

<tr id="foreach:item=list">
  <td>@{item}@</td>
</tr>

Output Program:

### 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>

Iteration(loop)

'id="loop:loopvar=list"' (or 'id="loop:loopvar:list"') is a directive for iteration. It iterates only contents. The start tag and the end tag are not iterated. It is very useful especially for <dl></dl> tag.

Presentation Data:

<dl id="loop:item=list">
  <dt>@{item.text}@</dt>
  <dd>@{item.desc}@</dd>
</dl>

Output Program:

### 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>

Iteration with Count

'id="Foreach:var=list"' and 'id="Loop:var=list"' are directives for iteration with loop counting. The counter variable is var_ctr. It starts at 1.

Presentation Data:

<tr id="Foreach:item=list">
  <td>@{item_ctr}@</td>
  <td>@{item}@<td>
</tr>

Output Program:

### 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>

Iteration with a Toggle Switch

'id="FOREACH:var=list"' and 'id="LOOP:var=list"' are directives for iteration with toggle switching. The toggle switch's value changes depending on whether loop counter is odd or even. The toggle switch is named var_tgl. The value of the toggle switch is '"odd"' or '"even"' by default. You can change them with the command-line option '--odd=value' and '--even=value', or constant variable ODD and EVEN in configuration file kwartz/config.rb.

Presentation Data:

<table>
  <tbody id="LOOP:item=list">
    <tr class="@{item_tgl}@">
      <td>@{item}@</td>
    </tr>
  </tbody>
</table>

Output Program:

### 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>

Iteration (while)

'id="while:expression"' is a directive to iterate with a while statement.

Kwartz will raise an error when compiling a while statement into JSP, because there is no custom tag in JSTL which is equivalent to a while statement.

Presentation Data:

<tr id="while:row=sth.fetch()">
  <td>@{row[0]}@</td>
</tr>

Output Program:

### 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 } ?>

Dummy data

'id="dummy:str"' is a directive for ignoring an element.

'str' has no effect. It is to make id attribute value to be unique in the HTML file.

Presentation Data:

<tr id="dummy:d1">
  <td>bar</td>
</tr>
<tr id="dummy:d2">
  <td>baz</td>
</tr>

Intermediate Code:

                          // Nothing

Output Program:

                          // Nothing

Replacement of Elements

'id="replace:name"' replaces an element with other element which is already marked with the name name.

Presentation Data:

<html>
  <body>
    <!-- breadcrumbs navigation -->
    <div id="mark:breadcrumbs">
      <a href="/">Home</a>
      &gt; <a href="/kwartz">Kwartz</a>
      &gt; <a href="/kwartz/ruby">Kwartz-ruby</a>
    </div>

   ....

    <div id="replace:breadcrumbs">
      Home &gt; Kwartz &gt; Kwartz-ruby
    </span>
  </div>
</html

Output Script:

<html>
  <body>
    <!-- breadcrumbs navigation -->
    <div>
      <a href="/">Home</a>
      &gt; <a href="/kwartz">Kwartz</a>
      &gt; <a href="/kwartz/ruby">Kwartz-ruby</a>
    </div>

   ....

    <div>
      <a href="/">Home</a>
      &gt; <a href="/kwartz">Kwartz</a>
      &gt; <a href="/kwartz/ruby">Kwartz-ruby</a>
    </div>
</html

The command-line option '-i file1,file2,...' enables you to use elements in other files.


Placeholder

'id="placeholder:name"' replaces content of the element by other element which is already marked with the name name. Usually this directive is used to import elements defined in other files, with the command-line option -i file1,file2,....

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

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

Compile:

$ kwartz -i article.html layout.html

Output Script:

<!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>

Including Presentation Data Files

id="include:filename" is a directive to read and to include another presentation data file (HTML file). Included data file can contain directives.

Presentation Data (copyright.html) :

<!-- begin footer -->
<center>
  copyright&copy; <span id="value:year">2005</span> kuwata-lab all rights reserverd
</center>
<!-- end footer -->

Presentation Data (mainpage.html) :

<html>
  <body>

    ... main contents ...

    <div id="include:copyright.html">
      ... copyright ...
    </div>

  </body>
</html>

Compile:

$ kwartz -l eruby mainpage.html > mainpage.view

Output Script:

### for eRuby
<html>
  <body>

    ... main contents ...

<!-- begin footer -->
<center>
  copyright&copy; <%= year %> kuwata-lab all rights reserverd
</center>
<!-- end footer -->

  </body>
</html>

'Include' and 'INCLUDE' directives are also available.

When presentation data files to be included are placed in other directories, you can specify those directories with the command-line option --incdirs=dir1,dir2,... or the constant INCDIRS in configuration file.


id and kw:d Attributes


Notes

These are some notes on the use of directives.



Command-line options

The script 'kwartz' is a commad-line script to compile templates (presentation data file and presentation logic file) into output scripts.

Usage: kwartz [options...] [-p plogic ] pdata.html > output-script

Options:

-h, --help
Print help.
-v
Version information.
-a action
Action to do. action may be one of the following (default is 'compile').
compile
Read presentation data and presentation logic, and generate output script.
analyze
Read presentation data and presentation logic, and report scope of variables.
convert
Read presentation data, and convert to PL program. This is for debugging.
translate
Read PL program, and translate into output script. This is for debugging.
-e , -s
Enable auto-sanitizing. This option is equal to --escape=true.
-i file1,file2,...
Import elements defined in outer files. Usually this option is used for 'placeholder' directive ('id="placeholder:name').
-l lang
Target language of the output script. lang may be eruby, erb, php, jstl11, jstl10.
-p plogic-file
Filename of the presentation logics. It is possible to specify several filename using ',' as a separator.
--charset=charset
Character set. Kwartz will print '<%@ page contentType="text/html; charset=charset" %>' in JSTL.
--dname=name
Attribute name used as a directive. Default is 'kw:d'.
--escape=true|false
Auto-sanitizing. If value is ommited then true is used as value.
--even=value
Even value. Default is 'even'. Directives FOREACH and LIST will use this value.
--extract=name
Extract an element which is marked with name name.
--footer=string
Footer string.
--header=string
Header string. '<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>' is used as default in JSP. If you don't want to print any header text, use --header=false.
--indent=' '
Specifies the indent space of output script.
--incdirs=dir1,dir2,...
Specify directories from which 'include' directive includes.
--odd=value
Odd value. Default is 'odd'. Directives FOREACH and LIST will use this value.
--rename=true|false
Specify rename or not local variable names. Regarded as true when value is omitted.

Examples:


Configuration options

You can sepcify Kwartz options in configuration file. Configuration file for Kwartz is different for each implementation. It is kwartz/config.rb in Kwartz-ruby.

The following is the options for Kwartz.

ESCAPE
Specify auto-sanitizing on/off.
NEWLINE
Specify a string which represents newline characters ("\n" or "\r\n") of output script. You don't have to change this option because Kwartz detects newline characters automatically.
INDENT
Specify a string which represents indent of output script.
RENAME
Specify whether rename local variable names. If true, '_' is added to beginning of local variable name.
RENAME_PREFIX
Specify the prefix of local variable name when RENAME is true.
LANG
Specify default language for output script.
ODD
Specify odd value of toggle variable. This is used by id="FOREACH:var=list" and id="LOOP:var=list".
EVEN
Specify even value of toggle variable. This is used by id="FOREACH:var=list" and id="LOOP:var=list".
DATTR
Specify an attribute name for directives. Default is 'kw:d'.
NOEND
List of tag name which doesn't require end tag. Default is [ "input", "br", "meta", "img", "hr" ].
CHARSET
Specify character encoding name for jstl11 and jstl10.
EMBED_PATTERN
Specify a pattern to embed expression into presentation data.
INCDIRS
Specify a list of directories from which 'include' directive includes. Default is [ "." ].