Kwartz-PHP Users' Guide
2 Features Detail
2-1 RuleSet and Properties
Format of presentation logic in Kwartz is similar to CSS (Cascading Style Sheet).
- Presentation logic file is a set of Ruleset.
- Ruleset is a pair of selector and declarations.
- Declaration is a pair of property name and value.
The following rules are available in presesntation logic file. These are similar to CSS. If you are familiar with CSS, you'll be so with Kwartz.
- stag: expr;
- Replace start-tag by expression value.
- etag: expr;
- Replace end-tag by expression value.
- elem: expr;
- Replace elemnt by expression value.
- cont: expr;
- Replace content of element by expressin value.
- value: expr;
-
Equivarent to
cont: expr.
- attrs: 'attrname' expr;
-
Replace attribute value by expression.
The following is an example to specify some attributes.
#foo { attrs: 'href' $item['url'], 'id' $item['id'], 'class' $classname; }
- append: expr;
-
Append expression value to tail of tag.
This is used especially to add 'checked="checked"', 'selected="selected"'
into the form control tag.
#checkbox1 { append: $member['age'] > 18 ? ' checked="checked"' : ''; } #select_options { append: $option['value'] == current_val ? ' selected="selected"' : ''; }
- remove: 'attr1', 'attr2', 'attr3';
- Remove the attributes from the element.
- logic: { ... }
- Logic of the element.
'stag:' and 'elem:' are useful especially for framework-specific functions. The following is an examle to use Kwartz in Symphony.
<form id="form">
Name: <input type="text" id="member_name"><br>
Birthday: <select id="member_birth">
<option> - </option>
</select><br>
<input type="submit" id="submit">
</form>
#form {
stag: start_form_tag("action='new'");
}
#member_name {
elem: text_field('member', 'name');
}
#member_birth {
elem: date_select('member', 'birth');
}
#submit {
elem: submit_to('Submit');
}
$ kwartz-php -p form1.plogic form1.html
<?php echo start_form_tag("action='new'"); ?>
Name: <?php echo text_field('member', 'name'); ?><br>
Birthday: <?php echo date_select('member', 'birth'); ?><br>
<?php echo submit_to('Submit'); ?>
</form>
2-2 Directives
Presentation logic may be embedded into presentation data in Kwartz. You can choose to separate or not to sepearate presentation logic from presentation data.
The reason to provide both solutions (separate or not) is choosability. Some preferes to separate presentation logic from presentaion data, and others may prefere to mix them. Both approaches have own advantages and disadvantages. Thus it is the user who determine which solution to adopt. Kwartz provides both approaches and you can select which to use. Kwartz doesn't enforce you to adopt a solution.
To embed presentation logic into presentation data, use directives. Directive is a command to embed presentation logic into presentation data. In Kwartz, 'kw:d' attributes(*4) are used to describe directives.
The following is an example to use directives.
- Directive
kw:d="foreach(list as var)"means to iterate the element. - Directive
kw:d="value(expression)"means to print value of expression as content of the element. - Directive
kw:d="dummy()"means that the element is a dummy and is not printed out.
<table>
<tr kw:d="foreach($members as $member)">
<td kw:d="value($member->name)">foo</td>
<td>
<a href="mailto:<?php echo $member->email; ?>"
kw:d="value($member->email)">foo@mai.com</a>
</td>
</tr>
<tr kw:d="dummy()">
<td>bar</td>
<td><a href="mailto:bar@mail.org">bar@mail.org</a></td>
</tr>
<tr kw:d="dummy()">
<td>baz</td>
<td><a href="mailto:baz@mail.net">baz@mail.net</a></td>
</tr>
</table>
$ kwartz-php directive1.html > directive1.php
<table>
<?php foreach ($members as $member) { ?>
<tr>
<td><?php echo $member->name; ?></td>
<td>
<a href="mailto:<?php echo $member->email; ?>"><?php echo $member->email; ?></a>
</td>
</tr>
<?php } ?>
</table>
If the first character of target attribute is a space, Kwartz recognize it as non-directive(*5).
<span kw:d="value($expr1)">foo</span> <span kw:d=" value($expr2)">bar</span>
$ kwartz-php directive2.html <span><?php echo $expr1; ?></span> <span kw:d="value($expr2)">bar</span>
Directives are different in each target language. For example, foreach loop is 'for item in list' in eRuby, 'foreach($list as $item)' in PHP, 'forEach(item in list)' in JSTL. See reference manual for details about directives.
2-3 Embed Expression in Presentation Data
It is able to embed expressions in presentation data file in each language format. For example, you can use '<%= ... %>' with eRuby, '#{...}' with Ruby, '<?php echo ... ?>' with PHP, and so on.
(Experimental) '@{...}@' and '@!{...}@' are also available as embedded expression notation in all languages. The former escapes expression and the latter does not escape expression.
<p class="<%= klass %>">Hello <%=h user %></p>
<p class="@!{klass}@">Hello @{user}@</p>
$ kwartz-php -l eruby embed1_eruby.html <p class="<%= klass %>">Hello <%=h user %></p> <p class="<%= klass %>">Hello <%=h user %></p>
<p class="#{klass}">Hello #{ERB::Util.h user}</p>
<p class="@!{klass}@">Hello @{user}@</p>
$ kwartz-php -l eruby embed1_ruby.html
_buf = ""; _buf << "<p class=\"#{klass}\">Hello #{ERB::Util.h user}</p>
<p class=\""; _buf << (klass).to_s; _buf << "\">Hello "; _buf << ERB::Util.h(user); _buf << "</p>\n";
; _buf
<p class="<?php echo $klass; ?>">Hello <?php echo htmlspecialchars($user); ?></p>
<p class="@!{$klass}@">Hello @{$user}@</p>
$ kwartz-php -l eruby embed1_php.html <p class="<?php echo $klass; ?>">Hello <?php echo htmlspecialchars($user); ?></p> <p class="<?php echo $klass; ?>">Hello <?php echo htmlspecialchars($user); ?></p>
2-4 Escape
Kwartz supports Automatic-escape and Partial-escape/unescape.
- If command-line option '
-e' is specified, values of 'value: expr' are escaped. (Automatic-escape) - '
Value: expr' always escapes value even when '-e' is not specified. (Partial-escape) - '
VALUE: expr' always doesn't escapes value even when '-e' is specified. (Partial-unescape)
<tr> <td id="mark:val1">foo</td> <td id="mark:val2">bar</td> <td id="mark:val3">baz</td> </tr>
#val1 {
value: $expr;
}
#val2 {
Value: $expr;
}
#val3 {
VALUE: $expr;
}
-e' option.$ kwartz-php -p escape1.plogic escape1.html <tr> <td><?php echo $expr; ?></td> <td><?php echo htmlspecialchars($expr); ?></td> <td><?php echo $expr; ?></td> </tr>
-e' option.$ kwartz-php -e -p escape1.plogic escape1.html <tr> <td><?php echo htmlspecialchars($expr); ?></td> <td><?php echo htmlspecialchars($expr); ?></td> <td><?php echo $expr; ?></td> </tr>
In the same way, 'Stag:', 'Etag:', 'Elem:',
'Cont:', 'Attrs:', and 'Append:' properties are
always escaped, 'STAG:', 'ETAG:', 'ELEM:',
'CONT:', 'ATTRS:', and 'APPEND:' properties are
never escaped.
Escape function or method is different for each tareget language. 'h()' is used in eRuby and 'htmlspecialchars()' in PHP. JSTL prints escaped value in default.
Directives kw:d="Value(expr)", kw:d="Attr('name'=>expr)", and kw:d="Append(expr)" always escape expression value even when the command-line option '-e' is not specified.
Directives kw:d="VALUE(expr)", kw:d="ATTR('name'=>expr)", and kw:d="APPEND(expr)" doesn't escape expression value even when the command-line option '-e' is specified.
Configuration option PROPERTY_ESCAPE in 'kwartz/config.rb' determines whether values are escaped or not in default. If this is true then Kwartz will escape values in default.
2-5 Multi-language
Kwartz now supports the following programming language.
- Ruby, eRuby(ERB, Erubis)
- PHP
- JSP (JSTL 1.1 and 1.2)
- ePerl [experimental]
Presentation logics must be described in each target language. It means that if you have wrote presentation logics in Ruby, they were not reusable for PHP project (but you can get full-power of Ruby in presentation logic).
The followings are examples of Ruby, eRuby, PHP, JSP, and ePerl.
<html>
<body>
<table>
<tr bgcolor="#CCCCFF" id="mark:row">
<td id="mark:name">Foo</td>
<td id="mark:mail">foo@mail.com</td>
</tr>
<tr bgcolor="#FFCCCC" id="dummy:row1">
<td>Bar</td>
<td>bar@mail.net</td>
</tr>
<tr bgcolor="#CCCCFF" id="dummy:row2">
<td>Baz</td>
<td>baz@mail.org</td>
</tr>
</table>
</body>
</html>
#row {
attrs: "bgcolor" color;
logic: {
@list.each_with_index do |user, i|
color = i % 2 == 1 ? '#FFCCCC' : '#CCCCFF'
_elem
end
}
}
#name {
Value: user[:name];
}
#mail {
value: user[:mail];
}
#row {
attrs: "bgcolor" $color;
logic: {
$i = 0;
foreach ($list as $user) {
$color = ++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF';
_elem();
}
}
}
#name {
Value: $user['name'];
}
#mail {
value: $user['mail'];
}
#row {
attrs: "bgcolor" color;
logic: {
<c:forEach var="user" items="${list}" varStatus="loop">
<c:set var="color" value="${loop.index % 2 == 0 ? '#FFCCCC' : '#CCCCFF'}"/>
_elem
</c:forEach>
}
}
#name {
Value: user.name;
}
#mail {
value: user.mail;
}
#row {
attrs: "bgcolor" $color;
logic: {
$i = 0;
foreach ($user in @list) {
$color = ++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF';
_elem();
}
}
}
#name {
Value: $user{'name'};
}
#mail {
value: $user{'mail'};
}
$ kwartz-php -l eruby -p table1.ruby.plogic table1.html > table1.eruby $ kwartz-php -l ruby -p table1.ruby.plogic table1.html > table1.rb $ kwartz-php -l pierubis -p table1.ruby.plogic table1.html > table1.pierubis $ kwartz-php -l php -p table1.php.plogic table1.html > table1.php $ kwartz-php -l jstl -p table1.jstl.plogic table1.html > table1.jsp $ kwartz-php -l eperl -p table1.eperl.plogic table1.html > table1.eperl
<html>
<body>
<table>
<% @list.each_with_index do |user, i| %>
<% color = i % 2 == 1 ? '#FFCCCC' : '#CCCCFF' %>
<tr bgcolor="<%= color %>">
<td><%=h user[:name] %></td>
<td><%= user[:mail] %></td>
</tr>
<% end %>
</table>
</body>
</html>
_buf = ""; _buf << "<html>
<body>
<table>\n";
@list.each_with_index do |user, i|
color = i % 2 == 1 ? '#FFCCCC' : '#CCCCFF'
_buf << " <tr bgcolor=\""; _buf << (color).to_s; _buf << "\">
<td>"; _buf << ERB::Util.h(user[:name]); _buf << "</td>
<td>"; _buf << (user[:mail]).to_s; _buf << "</td>
</tr>\n";
end
_buf << " </table>
</body>
</html>\n";
; _buf
<html>
<body>
<table>
<?rb @list.each_with_index do |user, i| ?>
<?rb color = i % 2 == 1 ? '#FFCCCC' : '#CCCCFF' ?>
<tr bgcolor="@!{color}@">
<td>@{user[:name]}@</td>
<td>@!{user[:mail]}@</td>
</tr>
<?rb end ?>
</table>
</body>
</html>
<html>
<body>
<table>
<?php $i = 0; ?>
<?php foreach ($list as $user) { ?>
<?php $color = ++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'; ?>
<tr bgcolor="<?php echo $color; ?>">
<td><?php echo htmlspecialchars($user['name']); ?></td>
<td><?php echo $user['mail']; ?></td>
</tr>
<?php } ?>
</table>
</body>
</html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<html>
<body>
<table>
<c:forEach var="user" items="${list}" varStatus="loop">
<c:set var="color" value="${loop.index % 2 == 0 ? '#FFCCCC' : '#CCCCFF'}"/>
<tr bgcolor="${color}">
<td>${user.name}</td>
<td>${user.mail}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
<html>
<body>
<table>
<? $i = 0; !>
<? foreach ($user in @list) { !>
<? $color = ++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'; !>
<tr bgcolor="<?= $color !>">
<td><?= encode_entities($user{'name'}) !></td>
<td><?= $user{'mail'} !></td>
</tr>
<? } !>
</table>
</body>
</html>
2-6 Span Tag Deletion
Kwartz regards span tags which contain only directives as dummy tags and delete them automatically when command-line option '--delspan' is specified.
<h1><span id="mark:title">title</span></h1> Hello <span kw:d="value($user)">World</span>!
#title {
value: $title;
}
$ kwartz-php -p delspan1.plogic --delspan delspan1.html <h1><?php echo $title; ?></h1> Hello <?php echo $user; ?>!
The span tags are not removed when they have other attributes.
Hello <span kw:d="value($user)" style="color:black">World</span>!
$ kwartz-php --delspan delspan2.html Hello <span style="color:black"><?php echo $user; ?></span>!
2-7 Import Presentation Logic File
'@imort "filename.plogic"' imports filename.plogic.
This is useful to share common presentation logic in many files.
#link_to_new {
elem: link_to('New', "member/new");
}
#link_to_show {
elem: link_to('Show', "member/show?id=".$member->getId());
}
#link_to_edit {
elem: link_to('Edit', "member/edit?id=".$member->getId());
}
#link_to_list {
elem: link_to('List', "member/list");
}
#link_to_destroy {
stag: link_to('Destroy', "member/destroy?id=".$member->getId());
}
<p> Name: <span id="mark:name">foo</span> <br> Email: <span id="mark:email">foo@mail.com</span> <br> </p> <a href="#" id="link_to_edit">Edit</a> | <a href="#" id="link_to_new">New</a> | <a href="#" id="link_to_list">List</a>
@import 'link_to.plogic';
#name {
Value: $member->name;
}
#email {
Value: $member->email;
}
$ kwartz-php -p show.plogic show.html
<p>
Name: <span><?php echo htmlspecialchars($member->name); ?></span> <br>
Email: <span><?php echo htmlspecialchars($member->email); ?></span> <br>
</p>
<?php echo link_to('Edit', "member/edit?id=".$member->getId()); ?> |
<?php echo link_to('New', "member/new"); ?> |
<?php echo link_to('List', "member/list"); ?>
2-8 Import Elements in Other Files
Command-line option '-i filename,...' imports element definitions form other files.
<form> <div id="mark:form_content"> Name: <input type="text"><br> Password: <input type="password"><br> </div> <input type="submit"> </form>
<form action="/new"> <div id="mark:placeholder"></div> <input type="submit" value="Create"> </form>
/* use element which is defined other file */
#placeholder {
logic: {
_content(form_content);
}
}
$ kwartz-php -i form.html -p new.plogic new.html <form action="/new"> Name: <input type="text"><br> Password: <input type="password"><br> <input type="submit" value="Create"> </form>
2-9 Extract Element
Command option '-X name' extracts element marked as name and command option '-x name' extracts content of element.
<html> <body> <div id="mark:content"> <h1>Show</h1> <p>Name: <span id="mark:name">foo</span></p> <p>Email: <span id="mark:email">foo@mail.com</span></p> </div> </body> </html>
#name {
value: $user->name;
}
#email {
value: $user->email;
}
$ kwartz-php -X content -p show.plogic show.html <div> <h1>Show</h1> <p>Name: <span><?php echo $user->name; ?></span></p> <p>Email: <span><?php echo $user->email; ?></span></p> </div>
$ kwartz-php -x content -p show.plogic show.html <h1>Show</h1> <p>Name: <span><?php echo $user->name; ?></span></p> <p>Email: <span><?php echo $user->email; ?></span></p>
2-10 Print Statement
Print statement is available in 'logic:' property.
<ul> <li id="items">foo</li> </ul>
#items {
logic: {
for item in list
_stag
print item
_etag
end
}
}
$ kwartz-php -l eruby -p print-stmt.eruby.plogic print-stmt.html <ul> <% for item in list %> <li id="items"><%= item %></li> <% end %> </ul>
#items {
logic: {
foreach ($list as $item) {
_stag();
print($item);
_etag();
}
}
}
$ kwartz-php -l php -p print-stmt.php.plogic print-stmt.html
<ul>
<?php foreach ($list as $item) { ?>
<li id="items"><?php echo $item; ?></li>
<?php } ?>
</ul>
#items {
logic: {
<c:forEach var="item" items="${list}">
_stag
print item
_etag
</c:forEach>
}
}
$ kwartz-php -l jstl -p print-stmt.jstl.plogic print-stmt.html
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<ul>
<c:forEach var="item" items="${list}">
<li id="items">${item}</li>
</c:forEach>
</ul>
$ kwartz-php -l jstl -p print-stmt.jstl.plogic --jstl=1.1 print-stmt.html
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<ul>
<c:forEach var="item" items="${list}">
<li id="items"><c:out value="${item}"/></li>
</c:forEach>
</ul>
It is recommended to use 'elem:', 'stag:', 'etag:', 'cont:', or 'value:' instead of print statement because they can escape or unescape exression value.
2-11 Add Code at Beginning/End of Document
'#DOCUMENT' is a special selector which represents the document. In '#DOCUMENT', properties 'begin:' and 'end:' are available to add codes at beginning/end of document.
<html> <body>hello</body> </html>
#DOCUMENT {
begin: {
$title = $_REQUEST['title'];
$user = $_REQUEST['user'];
}
end: {
print("<!--end-->\n");
}
}
$ kwartz-php -p document-test.plogic document-test.html <?php $title = $_REQUEST['title']; ?> <?php $user = $_REQUEST['user']; ?> <html> <body>hello</body> </html> <?php echo "<!--end-->\n"; ?>