Kwartz-PHP Users' Guide
3 Other Topics
3-1 Restrictions around presentation logic
There are several restrictions in presentation logic file.
- Position in which comment '
/* ... */' is available is limited. In the following example, 'value:' property will be error because string from 'expr;' to the end of comment is regared as argument of 'value:' property./* this comment is ok */ #foo { /* this comment is ok */ value: expr; /* this comment is NG! */ logic: { /* this comment is PHP comment */ foreach ($list as $item) { // PHP comment is OK in 'logic:' property _stag(); _cont(); _etag(); } } }
- '_stag', '_cont', '_etag', '_elem', '_element()', and '_content()' must be placed
one in per line, because Kwartz-ruby scans 'logic:' property with regular expression
pattern such as '/^\s*_(stag|cont|etag|element|content)(\(.*\))\s*$/' or so.
#foo { logic: { # OK if ($x > 0) { _elem(); } # NG (parse failed) if ($x > 0) { _elem(); } } }
- The number of '{' and '}' must be equal in 'logic:' property.
#foo { logic: { $str = "{"; # this will be parse error _elem(); } } #bar { logic: { $str = "{"; # add dummy '}' in comment! _elem(); } }
- '@import "file.plogic"' should be at the beginning of presentation logic file.
/* OK */ @import 'file1.plogic'; #foo { } /* NG */ @import 'file2.plogic';
3-2 Restrictions around presentation data
Kwartz parses presentation data file by regular expression pattern matching. It means that Kwartz doesn't use HTML parser nor XML parser for parsing presentation data. This approach enables Kwartz to handle any type of text file, and also brings the following restrictions to Kwartz.
- Cannot omit end tag if id attribute is specified.
<!-- Kwartz cannot parse the following because </li> is omitted. --> <ul> <li id="foo">foo </ul>
An Element which doesn't have any content is to be written as an empty tag such as<foo id="..."/>.
- However,
<input>,<br>,<meta>,<img>, and<hr>are allowed to omit end tag. And these doesn't have to be written as an empty tag.<!-- </input/> is omitted but Kwartz can parse correctly. --> <input type="text" name="user" id="user">
Configuration option PROPERTY_NOEND lists these tag names in file 'kwartz/config.rb'. Upper-case and lower-case are distinguished.
- Attribute values should be surrounded with '
"'.<!-- Kwartz fails parsing because attribute value is not surrounded with '"'. --> <h1 id='id:title' class=title>title</h1>
3-3 link_to() function in Symphony
link_to() function in Symphony is a little incompatible with Kwartz
because you must specify link label in both presentation data and presentation logic.
It's not DRY.
<a href="#" id="mark:link_to_new">Show member</a>
#link_to_new {
elem: link_to('Show member', "member/show?id=".$member->getId());
}
It is recommended to use start_link_tag(), start_remote_link_tag(), and start_function_link_tag() instead of link_to(), link_to_remote(), and link_to_function() because the formers print only start tag of anchor.
<a href="#" id="mark:link_to_new">Show member</a>
#link_to_new {
stag: start_link_tag("member/show?id=".$member->getId());
}
<a href="/member/show?id=123">Show member</a>
To use start_link_tag(), start_remote_link_tag(), and start_function_link_tag(), require 'Kwartz/Helper/Symfony.php'.
The following is the definition of 'Kwartz/Helper/Symfony.php'.
function start_link_tag($options = '', $html_options = array()) {
$s = link_to('', $options, $html_options);
return preg_replace('/<\/a>\z/', '', $s);
}
function start_remote_link_tag($options = array(), $html_options = array()) {
$s = link_to_remote('', $options, $html_options);
return preg_replace('/<\a>\z/', '', $s);
}
function start_function_link_tag($function, $html_options = array()) {
$s = link_to_function('', $function, $html_options);
return preg_replace('/<\a>\z/', '', $s);
}
3-4 Makefile and Rakefile
The followings are examples of Makefile, Rakefile, Rantfile, and Rookbook.
.SUFFIXES: .rhtml .html .plogic ALL = file1.rhtml file2.rhtml file3.rhtml LAYOUT = layout.html default: $(ALL) %.rhtml: %.html %.plogic kwartz-php -l eruby -p $*.plogic $*.html > $@ file3.rhtml: file3.html file3.plogic $(LAYOUT) kwartz-php -p file3.plogic -L $(LAYOUT) file3.html > file3.rhtml
all = ["file1.rhtml", "file2.rhtml", "file3.rhtml"]
layout = 'layout.html'
task :default => all
rule '.rhtml' => ['.html', '.plogic'] do |t|
pdata, plogic = t.sources
sh "kwartz-php -l eruby -p #{plogic} #{pdata} > #{t.name}"
end
file 'file3.rhtml' => ["file3.html", "file3.plogic", layout] do |t|
pdata, plogic, layout = t.prerequisites
sh "kwartz-php -p #{plogic} -L #{layout} #{pdata} > #{t.name}"
end
all = ["file1.rhtml", "file2.rhtml", "file3.rhtml"]
layout = 'layout.html'
task :default => all
gen Rule, ".rhtml" => [".html", ".plogic"] do |t|
pdata, plogic = t.prerequisites
sys "kwartz-php -p #{plogic} #{pdata} > #{t.name}"
end
file "file3.rhtml" => ["file3.html", "file3.plogic", layout] do |t|
pdata, plogic, layout = t.prerequisites
sys "kwartz-php -p #{plogic} -L #{layout} #{pdata} > #{t.name}"
end
properties:
- layout : layout.html
parameters:
- all : [ file1.rhtml, file2.rhtml, file3.rhtml ]
- rook_product: $(all)
recipes:
- product: *.rhtml
ingreds: [ $(1).html, $(1).plogic ]
method*: |
$pdata = $ingreds[0]; $plogic = $ingreds[1];
k_sys("kwartz-php -p $plogic} $pdata > $product");
- product: file3.rhtml
ingres: [ file3.html, file3.plogic, $(layout) ]
method*: |
$pdata = $ingreds[0]; $plogic = $ingreds[1]
k_sys("kwartz-php -p $plogic -L $(layout) $pdata > $product"
properties:
- layout : layout.html
parameters:
- all : [ file1.rhtml, file2.rhtml, file3.rhtml ]
- rook_product: $(all)
recipes:
- product: *.rhtml
ingreds: [ $(1).html, $(1).plogic ]
method*: |
pdata, plogic = @ingreds
sys "kwartz-php -p #{plogic} #{pdata} > #{@product}"
- product: file3.rhtml
ingres: [ file3.html, file3.plogic, $(layout) ]
method*: |
pdata, plogic, layout = @ingreds
sys "kwartz-php -p #{plogic} -L $(layout) #{pdata} > #{@product}"
3-5 Use Kwartz as Library
If you want to use Kwartz library in your PHP script, use KwartzMain class.
require 'Kwartz';
require 'kwartz/Main';
$argv = array('-p', 'hello.plogic', '-L', 'layout.html', 'hello.html');
$main = new KwartzMain($argv)
$output = $main->execute()
file_put_content('hello.php', $output);
3-6 Use Kwartz with Non-Supported Language
Using Erubis, it is able to use Kwartz with Java, JavaScript, Scheme, and so on. Erubis is an implementation of eRuby which supports not only Ruby but also other languages.
The followings are examples of using JavaScript with Kwartz and Erubis.
<table>
<tr class="odd" id="mark:list">
<td>@{item}@</td>
</tr>
<tr class="even" id="dummy:d1">
<td>foo</td>
</tr>
</table>
#list {
attrs: 'class' klass;
logic: {
for (var i=0, len=list.length; i < len; i++) {
klass = i % 1 == 0 ? 'even' : 'odd';
item = list[i];
_elem;
}
}
}
$ kwartz-php -l erubis -p js-example.plogic js-example.html > js-example.jshtml
<table>
<% for (var i=0, len=list.length; i < len; i++) { %>
<% klass = i % 1 == 0 ? 'even' : 'odd'; %>
<% item = list[i]; %>
<tr class="<%= klass %>">
<td><%== item %></td>
</tr>
<% } %>
</table>
In Erubis, <%= ... %> means embedded expression and <%== ... %> means embedded expression with escaping.
In this example, @{item}@ is compiled into <%== item %> because it needs escaping and attr: 'class' klass is compiled into <%= klass %> without escaping.
The following is an example to compile into JavaScript code with Erubis.
$ erubis -l javascript -x js-example.jshtml
var _buf = []; _buf.push("<table>\n");
for (var i=0, len=list.length; i < len; i++) {
klass = i % 1 == 0 ? 'even' : 'odd';
item = list[i];
_buf.push(" <tr class=\""); _buf.push(klass); _buf.push("\">\n\
<td>"); _buf.push(escape(item)); _buf.push("</td>\n\
</tr>\n");
}
_buf.push("</table>\n");
document.write(_buf.join(""));