Kwartz-PHP Users' Guide

3   Other Topics

3-1   Restrictions around presentation logic

There are several restrictions in presentation logic file.

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.

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.

presentation data
<a href="#" id="mark:link_to_new">Show member</a>
presentation logic
#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.

presentation data
<a href="#" id="mark:link_to_new">Show member</a>
presentation logic
#link_to_new {
  stag:  start_link_tag("member/show?id=".$member->getId());
}
expected result
<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'.

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.

example of Makefile
.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
example of Rakefile for Rake
all    = ["file1.rhtml", "file2.rhtml", "file3.rhtml"]
layout = 'layout.html'

task :default => all

rule '.rhtml' => ['.html', '.plogic']           do |t|
  pdata, plogic = t.sources
  sh "kwartz-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
example of Rantfile for Rant
all    = ["file1.rhtml", "file2.rhtml", "file3.rhtml"]
layout = 'layout.html'

task :default => all

gen Rule, ".rhtml" => [".html", ".plogic"] do |t|
  pdata, plogic = t.prerequisites
  sys "kwartz-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
example of Kookbook.yaml for Kook
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"
example of Rookbook.yaml for Rook
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.

usage of 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.

presentation data (js-example.html)
<table>
  <tr class="odd" id="mark:list">
    <td>@{item}@</td>
  </tr>
  <tr class="even" id="dummy:d1">
    <td>foo</td>
  </tr>
</table>
presentation logic (js-example.plogic)
#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;
    }
  }
}
compile
$ kwartz-php -l erubis -p js-example.plogic js-example.html  > js-example.jshtml
output script (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.

convert 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(""));