Kwartz Reference Manual
last update: $Date: 2005-07-04 00:36:10 +0900 (Mon, 04 Jul 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
- Preface
- PL - Presentation Language
- Directives
- What is a Directive?
- Marking
- Printing Values of Expressions
- Printing value of expression 2
- Attribute Values
- Appending Attribute Expression
- Assignment
- Conditional Branching
- Iteration (foreach)
- Iteration(list)
- Iteration with Count
- Iteration with a Toggle Switch
- Iteration (while)
- Iteration (loop)
- Dummy data
- Replacement of Elements
- Placeholder
- Including Presentation Data Files
- id and kw:d Attributes
- Notes
- Presentation Logic File Format
- Command-line options
- Configuration options
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.
Also is a comment between '/*
' and '*/
'.
// 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.
Language name | true | false | null |
---|---|---|---|
PHP | TRUE | FALSE | NULL |
eRuby | true | false | nil |
JSP(JSTL) | true | false | null |
Velocity | true | false | - |
Translating a PL program which contains the keyword null
into a Velocity script will cause an error
because Velocity doesn't have a keyword which is equivalent to null
.
However, Kwartz will translate 'expr==null
' and 'expr!=null
' to '!expr
' and 'expr
'
when translating to Velocity.
flag = obj == null? true : false; if (expr != null) { print("expr is not null.\n"); } else { print("epxr is null.\n"); }
### for Velocity #if($obj) #set($flag = true) #else #set($flag = false) #end #if(! $expr) expr is not null. #else epxr is null. #end
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).
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.
Concatenation operator will be error in Velocity.
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'}"/>
Conditional Operator is available in eRuby, PHP, and JSTL1.1. However, it is not available in JSTL1.0 and Velocity. Therefore, conditional operators will be translated to corresponding if statements in JSTL1.0 and velocity.
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> ### for Velocity #if($ctr % 2 == 0) #set($color = "#FFCCCC") #else #set($color = "#CCCCFF") #end
- (*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.
print('foo', bar, "baz\n"); // print a string and the value of a variable
### for eRuby foo<%= bar %>baz ### for PHP foo<?php echo $bar; ?>baz ### for JSTL foo<c:out value="${bar}" escapeXml="false"/>baz ### for Velocity foo$!{bar}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 ### for Velocity foo$!esc.html($bar)baz
If conditional operator returns constant string or number, sanitizing will be off even when using auto-sanitizing.
// Sanitized. print("<option ", condition ? var1 : var2, ">\n"); // Not sanitized. 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"/>>
'print(a .+ b .+ c);
' will be expanded such as 'print(a); print(b); print(c);
'.
This is for some languages which doesn't support string concatenation operator (.+
).
Assignment
Assignment statement is such as var = 100;
.
Also '+=
', '-=
', '*=
', '/=
', '%=
' and '+=
' are allowed.
name = 'Foo'; // assign a string count += 1; // increment the value of the variable str .+= '.txt'; // append a string
### 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.
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
### 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:
Target language | Result of translation |
---|---|
eRuby | hash[:key] |
PHP | $hash['key'] |
JSTL | hash['key'] |
Velocity | hash.key |
print(hash[:key]);
### for eRuby <%= hash[:key] %> ### for PHP <?php echo $hash['key']; ?> ### for JSTL <c:out value="${hash['key']}" escapeXml="false"/> ### for Velocity $!{hash.key}
- (*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.
// 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"/> ### for Velocity #set($user.name = "Foo") $!{user.name}
// method call print(user.method(10, 20));
### for eRuby <%= user.method(10, 20) %> ### for PHP <?php echo $user->method(10, 20); ?> ### for Velocity $!{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.
foreach(item in list) { 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> ### for Velocity #foreach($item in $list) $!{item} #end
You can also use a while statment. Kwartz will raise an error if you try to translate a while statement into a JSTL or Velocity script, because there is no JSTL tag or Velocity directive which is equivalent to the while statment.
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 } ?>
for-statements (like in C or Java) are not available.
Conditional Branching
'if(condition) { ... } else if(condition) { ... } else { ... }
' represents a conditional branch.
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> ### for Velocity #if($val > 0) * value is positive. #elseif($val < 0) * value is negative. #else * value is zero. #end
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. E() is pseudo-function and allowed to appear only as argument of print statement.
- X(expr)
- Don't sanitize expression expr, even when the command-line option for sanitizing is specified. X() is pseudo-function and allowed to appear only as argument of print statement.
- 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.
- list_empty(list)
- Return true if list is empty or false if not empty.
- hash_new()
- Create a new hash.
- hash_length(hash)
- Return the count of the hash.
- hash_empty(hash)
- Return true if hash is empty or false if not empty.
- hash_keys(hash)
- Return a list which contains all keys of the hash.
- str_length(string)
- Return the length of the string.
- str_empty(string)
- Return true if string is empty, or false if not empty.
- 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.
- str_replace(string, before, after)
- Replace before to after in string and return it.
- str_linebreak(string)
-
Insert
<br />
before newline character in string and return it.
- escape_xml(html_string)
- return the sanitaized html_string.
- escape_url(url_string)
- Encode url_string and return it.
- escape_sql(sql_string)
-
Escape quotation(
'
), double quotation("
), backslash(\
) in sql_string with backslash and return it.
The following table shows the translation of functions in each target languages.
Functions | eRuby, ERB | PHP | JSTL1.1 | Velocity |
---|---|---|---|---|
list_new() |
[] |
array() |
- | - |
list_length(list) |
list.length |
array_length(list) |
fn:length(list) |
(list).size() |
list_empty(list) |
list.empty? |
array_length(list)==0 |
fn:length(list)==0 |
(list).size()==0 |
hash_new() |
{} |
array() |
- | - |
hash_length(hash) |
hash.length |
array_length(hash) |
fn:length(hash) |
hash.size() |
hash_empty(hash) |
hash.empty? |
array_length(hash)==0 |
fn:length(hash)==0 |
hash.size()==0 |
hash_keys(hash) |
hash.keys |
array_keys(hash) |
- | hash.keySet().toArray() |
str_length(str) |
str.lenth |
strlen(str) |
fn:length(str) |
str.length() |
str_tolower(str) |
str.downcase |
strtolower(str) |
fn:toLowerCase(str) |
str.toLowerCase() |
str_toupper(str) |
str.upcase |
strtoupper(str) |
fn:toUpperCase(str) |
str.toUpperCase() |
str_index(str,ch) |
str.index(ch) |
strchr(str,ch) |
fn:indexOf(str,ch) |
str.indexOf(ch) |
str_replace(str,before, after) |
str.gsub(before,after) |
str_replace(before,after,str) |
fn:replace(str,before,after) |
str.indexOf(ch) |
str_linebreak(str) |
str.gsub(/\r?\n/,'<br />\&') |
nl2br(str) |
fn:replace(str,'\n','<br />\n') |
str.replaceAll('$','<br />') |
escape_xml(str) |
CGI::escapeHTML(str) (when eRuby) html_escape(str) (when ERB) |
htmlspecialchars(str) |
fn:escapeXml(str) |
$esc.xml(str) |
escape_url(str) |
CGI::escape(str) (when eRuby) url_encode(str) (when ERB) |
urlencode(str) |
- | $link.setURI(str).toString() |
escape_sql(str) |
str.gsub(/['"\\\0]/,'\\\&') |
addslashes(str) |
- | $esc.sql(str) |
All functions except above are printed "as is" when translating into eRuby or PHP script. Translating into JSTL or Velocity script will be error.
Functions E() and X() are intended to be used as arguments of print statement. You shouldn't use them in other place.
If you want to use the following functions in Velocity, you need to install VelocityTools.
escape_xml()
andescape_sql()
requires EscapeTools.escape_url()
requries LinkTools.
See each documentation for details.
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 '!=
'.
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> ### for Velocity #if(! $str1 || $str1 == "") str1 is empty. #elseif($str2 && $str2 != "") str2 is not empty. #end
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
.
-
attrs: "attr1" expr1 , "attr2" expr2 , ... ;
-
Replace value of attribute
attr
by value ofexpr
.
-
remove: "attr1" , "attr2" , ... ;
-
Remove attribute
attr
.
-
append: expr1 , expr2 , ... ;
-
Append expression
expr
at the end of start tag. This is useful for appendingchecked
orselected
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.@element(other)
is also available which represents other element and@content(other)
represents content of other element.
<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; attrs: "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> ### for Velocity <ul> #foreach($item in $list) <li id="foo" class="$!{klass}">$!{item}</li> #end </ul> <form action="foo.cgi"> #if($flag) <html:text type="checkbox" name="user" value="Y" checked /> #else <html:text type="checkbox" name="user" value="Y" /> #end </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.
<ul id="mark:list"> <li id="value:item">foo</li> </ul>
#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. --> ### for Velocity #set($list = $context.list) <ul> #foreach($item in $list) <li>$!{item}</li> #end </ul> <!-- copyright(c) 2005 kuwata-lab.com ALL RIGHTS RESERVERD. -->
Rawcode
Kwartz allow you to write code of target language (Ruby, PHP, Java, etc) directly in presentation logic. These are called `Raw Code'. There are two type of raw code: expression and statement.
<%=expression%>
and<?=expression?>
represents raw code expression. They are treated as literal like string and number.<%statement%>
and<?statement?>
represents raw code statement. They are treated as a statment. Semicolon (';
') is not needed at the end of the statement.
The following is an example to write Ruby code directly.
// Rawcode expression hash = <%= { :a => 123, :b => 456, :c => 789, } %>; // Rawcode statement <% hash.each do |key, value| %> print("key=", key, " value=", value, "\n"); <% end %>
### for eRuby <% hash = { :a => 123, :b => 456, :c => 789, } %> <% hash.each do |key, value| %> key=<%= key %> value=<%= value %> <% end %>
The following is an example which includes PHP code.
// Rawcode expression hash = <?= array("a"=>123, "b"=>456, "c"=>789) ?>; // Rawcode statement <?php foreach($hash as $key => $value) { ?> print("key=", key, " value=", value, "\n"); <?php } ?>
### for PHP <?php $hash = array("a"=>123, "b"=>456, "c"=>789); ?> <?php foreach($hash as $key => $value) { ?> key=<?php echo $key; ?> value=<?php echo $value; ?> <?php } ?>
Rawocde statement is available at the `plogic:' part of the element declaration.
Rawcode expression is available at the `value:' part, `attrs:' part, or `append:' part.
You can prevent to sanitize rawcode expression if you write X(<%= ... %>)
.
There is an example which use Kwartz with Ruby on Rails in examples/rails1 directory of Kwartz archive.
You should remember that writing a raw-code takes portability away.
Global and Local Variables
In Kwartz, variables are called 'Template Global Variables' if they are set in the main program and are passed to output script. Variables are called 'Template Local Variables' if they are used only in the template.
Assume the following presentation data and presentation logic:
<table> <caption id="value:title">Sample</caption> <tr id="mark:items" bgcolor="@{color}@"> <td id="value:item">Foo</td> </tr> </table>
#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:
- Template global variables
-
The variables '
title
' and 'list
' need to be set in the main program and be passed to template. These variables are called 'Template Global Variables' in Kwartz. - Template local variables
-
The variables '
item
', 'ctr
', and 'color
' are used only in the template. These variables are called 'Template Local Variables' in Kwartz.
Invoking Kwartz with the command-line option '-a analyze
' analyzes the template and reports template global/local variables.
$ kwartz -p analyze.plogic -a analyze analyze.html Global: title list Local: ctr item color
Kwartz detemines whether variables are global or local according to the following rule:
- When Kwartz finds a new variable ...
- If it appears in the lefthand-side of an assignment, it is to be recognized as a template local variable.
- If it appears as the loop variable of a foreach statement, it is to be recognized as a template local variable.
- Otherwize, it is to be recognized as a template global variable.
Kwartz reports warnings if template global variables appear in the lefthand-side of assignments or are used as loop variables in foreach statements. Because the role of template system is to display template global variables, templates should not change or modify template 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).
- break, continue
- user-defined functions/procedures
- creating arrays and hashes in JSTL
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;
- Kwartz doesn't break HTML design. Compare to Jakarta Velocity or Template-Toolkit.
- Kwartz doesn't need complex programming. Compare to Enhydra XMLC, which needs complex DOM programming.
- Kwartz works very quickly and is light-weight. Compared to amrita.
- Kwartz can handle any type of text. Compare to Enhydra XMLC or amrita.
- Kwartz can be used in several languages. There is no other template system like this!
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.
<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> ### for Velocity <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).
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"/>! ### for Velocity Hello $!{user.name}!
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.
-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}"/>! ### for Velocity Hello $!esc.html($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
'.
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"/>! ### for Velocity With sanitizing: $!esc.html($var)! Without sanitizing: $!{var}!
. .
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.
<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> ### for Velocity <li>$!{hash["name"]}</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
'.
<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> ### for Velocity <tr class="$!{klass}"> <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.
<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> ### for Velocity #if($message && $message != "") <font class="$!{klass}" bgcolor="$!{color}"> $!{message} </font> #end
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>'.
<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>
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.
<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
Assignment
'id="set:var=value"
' is a directive for assigning values into variables.
Other than '=
', '+=
', '-=
', '*=
', '/=
', '.=
' are also available.
<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> ### for Velocity #set($var = $value) <dt>foo</dt> #set($count = $count + 1) <dd>123</dd>
Conditional Branching
'id="if:expression"
' is a directive for conditional branching.
'else
' and 'elseif
' are also available.
<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> ### for Velocity #if($value > 0) <div> Value is positive. </div> #elseif($value < 0) <div> Value is negative. </div> #else <div> Value is zero. </div> #end
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.
<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> ### for Velocity #foreach($item in $list) <tr> <td>$!{item}</td> </tr> #end
Iteration(list)
'id="list:loopvar=list"
' (or 'id="list: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.
<dl id="list: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> ### for Velocity <dl> #foreach($item in $list) <dt>$!{item.text}</dt> <dd>$!{item.desc}</dd> #end </dl>
NOTICE: list
directive was named loop
in previous version of Kwartz-ruby.
However loop
directive is planned to mean as inner loop of while
,
so you should use list
directive from now on.
Iteration with Count
'id="Foreach:var=list"
' and 'id="List:var=list"
' are directives for iteration with loop counting.
The counter variable is var_ctr
. It starts at 1.
<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> ### for Velocity #set($item_ctr = 0) #foreach($item in $list) #set($item_ctr = $item_ctr + 1) <tr> <td>$!{item_ctr}</td> <td>$!{item}<td> </tr> #end
NOTICE: List
directive was named Loop
in previous version of Kwartz-ruby.
However Loop
directive is planned to mean as inner loop of while
,
so you should use List
directive from now on.
Iteration with a Toggle Switch
'id="FOREACH:var=list"
' and 'id="LIST: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.
<table> <tbody id="LIST: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> ### for Velocity <table> <tbody> #set($item_ctr = 0) #foreach($item in $list) #set($item_ctr = $item_ctr + 1) #if($item_ctr % 2 == 0) #set($item_tgl = "even") #else #set($item_tgl = "odd") #end <tr class="$!{item_tgl}"> <td>$!{item}</td> </tr> #end </tbody> </table>
NOTICE: LIST
directive was named LOOP
in previous version of Kwartz-ruby.
However LOOP
directive is planned to mean as inner loop of while
,
so you should use LIST
directive from now on.
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 or Velocity, because there is no custom tag in JSTL nor Directives in Velocity which is equivalent to while statement.
<table id="while:row=sth.fetch()"> <tr><td>name:</td><td>@{row[0]}@</td></tr> <tr><td>mail:</td><td>@{row[1]}@</td></tr> </table>
### for eRuby <% while row = sth.fetch() do %> <table> <tr><td>name:</td><td><%= row[0] %></td></tr> <tr><td>mail:</td><td><%= row[1] %></td></tr> </table> <% end %> ### for PHP <?php while ($row = $sth->fetch()) { ?> <table> <tr><td>name:</td><td><?php echo $row[0]; ?></td></tr> <tr><td>mail:</td><td><?php echo $row[1]; ?></td></tr> </table> <?php } ?>
Iteration (loop)
CAUTION: This is a plan and not implemented yet
'id="loop:expression"
' is a directive to iterate with a while statement.
Difference between while
directive is that loop
directive iterates only content of the element
and while
directive iterates start tag, content, and end tag of the element.
Kwartz will raise an error when compiling a while statement into JSP or Velocity, because there is no custom tag in JSTL nor Directives in Velocity which is equivalent to loop(while) statement.
<table id="loop:row=sth.fetch()"> <tr><td>name:</td><td>@{row[0]}@</td></tr> <tr><td>mail:</td><td>@{row[1]}@</td></tr> </table>
### for eRuby <table> <% while row = sth.fetch() do %> <tr><td>name:</td><td><%= row[0] %></td></tr> <tr><td>mail:</td><td><%= row[1] %></td></tr> <% end %> </table> ### for PHP <table> <?php while ($row = $sth->fetch()) { ?> <tr><td>name:</td><td><?php echo $row[0]; ?></td></tr> <tr><td>mail:</td><td><?php echo $row[1]; ?></td></tr> <?php } ?> </table>
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.
<tr id="dummy:d1"> <td>bar</td> </tr> <tr id="dummy:d2"> <td>baz</td> </tr>
// Nothing
// Nothing
Replacement of Elements
'id="replace:name"
' replaces an element with other element
which is already marked with the name name.
'id="replace:name:content"
' replaces an element with content of other element.
<html> <body> <!-- breadcrumbs navigation --> <div id="mark:breadcrumbs"> <a href="/">Home</a> > <a href="/kwartz">Kwartz</a> > <a href="/kwartz/ruby">Kwartz-ruby</a> </div> .... <!-- replace an element by other element --> <div id="replace:breadcrumbs"> Home > Kwartz > Kwartz-ruby </div> <!-- replace an element by content of other element --> <div id="replace:breadcrumbs:content"> Home > Kwartz > Kwartz-ruby </div> </body> </html
<html> <body> <!-- breadcrumbs navigation --> <div> <a href="/">Home</a> > <a href="/kwartz">Kwartz</a> > <a href="/kwartz/ruby">Kwartz-ruby</a> </div> .... <!-- replace an element by other element --> <div> <a href="/">Home</a> > <a href="/kwartz">Kwartz</a> > <a href="/kwartz/ruby">Kwartz-ruby</a> </div> <!-- replace an element by content of other element --> <a href="/">Home</a> > <a href="/kwartz">Kwartz</a> > <a href="/kwartz/ruby">Kwartz-ruby</a> </body> </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.
'id="placeholder:name:content"
' replaces content of the element by content of other element.
Usually this directive is used to import elements defined in other files,
with the command-line option -i file1,file2,...
.
<html> <body> <h1 id="mark:title">Kwartz Reference Manual</h1> <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>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html lang="en"> <head> <title id="placeholder:title:content">...title...</title> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <link rel="stylesheet" type="text/css" href="design.css"> </head> <body> <h1 id="placeholder:title:content">...title...</h1> <table border="0"> <tr> <td width="400" id="placeholder:article:content"> 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> <title>Kwartz Reference Manual</title> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <link rel="stylesheet" type="text/css" href="design.css"> </head> <body> <h1>Kwartz Reference Manual</h1> <table border="0"> <tr> <td width="400"> <p>Kwartz is a template system, which realized the concept <strong>`Separation of Presentation Logic and Presentation Data'(SoPL/PD)</strong>. </p> </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.
<!-- begin footer --> <center> copyright© <span id="value:year">2005</span> kuwata-lab all rights reserverd </center> <!-- end footer -->
<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
' and 'INCLUDE
' directives are also available.
- '
include
' directive replaces the element by presentation data included. - '
Include
' directive inserts the presentation data included before the element. - '
INCLUDE
' directive inserts the presentation data included after the element.
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
- The kw:d attribute is equivalent to the id attribute in Kwartz. Anything that can go in an id attribute can also be placed in a kw:d attribute.
- If a tag has both an id attribute and a kw:d attribte,
Kwartz overrides the former with the latter.
For example, if you write '
id="name" kw:d="foreach:item=list"
',
- However, if the kw:d attribute has only
attr
directives, then the id attribute is not overwritten. For example, if you write 'id="name" kw:d="attr:href=url"
, the element is marked with the namename
.
- The HTML Specification defines that the id attribute value can contain only alphanumeric characters, underscores (
_
), colons(:
), hyphens(-
) and periods(.
). Other characters cannot be in the id attribute. This means thatid="foreach:item=list"
orid="attr:name=value"
are not valid according to the HTML Specification. Therefore, it is recommended to writeid="foreach:item:list"
orid="attr:name:value"
instead.
- You can change the kw:d attribte name with the command-line option
--dattr=xxx
. For example,--dattr=style
make Kwartz to use 'style' attributes instead of 'kw:d' attributes. ConstantDATTR
in configuration file also enables you to change 'kw:d' attribute name.
Notes
These are some notes on the use of directives.
- One id or kw:d attribute can have only one directive.
For example, '
id="set:var=100;value:var"
' causes an error.## NG <span id="set:var=100;value:var">foo</span>
- However, the '
attr:name=value
' directive and the 'append=expression
' directive can be used with other directive in an id attribute, as well as with itself.## OK <foo id="foreach:item=list;attr:class=item.class;attr:href=item.url"> .... </foo>
- You cannot omit end-tags when using Kwartz directives.
But you can use empty-element tags, such as '
<foo .../>
'.## NG <ul> <li id="value:item">foo </ul> ## OK <a id="attr:name=refname"/>
- The <span></span> tag is deleted if it has only directives.
For example, the presentation data '
Hello <span id="value:name">World</span>!
' will be converted into the output script 'Hello <%= name %>!
' (in eRuby), deleting <span></span>.## presentation data Hello <span id="value:name">World</span>! ## output script for eRuby Hello <%= name %>!
- You must describe attributes like
attr="value"
in the start tag which contains directives. In other words, you cannot omit attribute names or attribute values when using directives. This is not a bug; it's an intended behavior so as to make Kwartz available in any text file.## 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' : ''}@>
Presentation Logic File Format
The following is an example of presentation logic file.
// element declaration for 'id="mark:name"' #name { // print value of expression instead of content value: expression; // set attribute values attrs: "attr1" expr1, "attr2" expr2, "attr3" expr3; // remove attributes remove: "attr1", "attr2", "attr3"; // append expression to start tag append: expr1, expr2, expr3; // change tag name tagname: "tagname", // set presentation logic plogic: { @stag; @cont; @etag; } } // document declaration #DOCUMENT { // logics to do at the beginning of the document begin: { ... } // logics to do at the end of the document end: { ... } // load presentation logic file required require: "file1.plogic", "file2.plogic"; }
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.
- defun
- Read presentation data and presentation logic, and define function of Ruby or PHP.
- 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, velocity.
- -p plogic-file
-
Filename of the presentation logics. It is possible to specify several filename using '
,
' as a separator.
- -R arg
-
Special option. Currently, only the following argument is avairable.
- ails ... Equivarent to
-l erb --globalvar-prefix='@'
. Make output script for Ruby on Rails.
- ails ... Equivarent to
- --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.
- --localvar-prefix=string
- Prefix of template local variables.
- --globalvar-prefix=string
- Prefix of template global variables.
Examples:
- Compile presentation data file 'file1.html' and get an output script 'file1.rhtml'.
The target language is eRuby.
$ kwartz -l eruby file1.html > file1.rhtml
- Compile presentation data file 'file1.html' and a presentation logic file 'file1.plogic', and get an output script 'file1.php'.
The target language is PHP.
$ kwartz -l php -p file1.plogic file1.html > file1.php
- Convert presentation data into PL program.
$ kwartz -a convert file1.html | more
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.
- LOCALVAR_PREFIX
- Specify the prefix of template local variable name.
- GLOBALVAR_PREFIX
- Specify the prefix of template global variable name.
- LANG
- Specify default language for output script.
- ODD
-
Specify odd value of toggle variable.
This is used by
id="FOREACH:var=list"
andid="LOOP:var=list"
.
- EVEN
-
Specify even value of toggle variable.
This is used by
id="FOREACH:var=list"
andid="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" ].
- DEFUN_CLASS
- Default name of class or module when defining functions with the command-line option '-a defun'.
- DEFUN_FUNCTION
- Default name of function or method when defining functions with the command-line option '-a defun'.
- 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 [ "." ].