.=title:	Kwartz User's Guide
.?author:	Makoto Kuwata <kwa(at)kuwata-lab.com>
.?lastupdate:	$Date: 2004/05/09 14:25:20 $
.?version:	$Revision: 0.16 $


.$ Preface | preface*


This is a user's guide of Kwartz{{(Development of Kwartz is subsidized by Exploratory Software Project of {{<IPA (Information-Technology Promotion Agency Japan)|http://www.ipa.go.jp/about/english/index.html>}}.)}}, a template system for web-designer and web-programmer.

{{*Sorry for my poor English. You may need imagination and patience to read this document.*}}



.$$ Table of Contents	| toc*

.+toc:
   .<<< users-guide.en.toc
.-toc:


.$$ Changelog		| changelog*

.: 2004-05-09
	.- "..." is also string literal, in addition to '...'.
	.- auto-detect "\n" or "\r\n".
	.- command line option "--delete_idattr" which delete id attribute from presentation data.
.: 2004-04-23
	.- new language ruby2 and php2
	.- updated about 'mkmethod'
.: 2004-04-04
	.- utility script 'mkmethod'
	.- tips to get result as string
	.- fixed 'import()' => 'include()' in PHP
.: 2004-04-01
	.- 'include' directive.
	.- 'load' directive and :load() statement.
	.- function E() and X()
.: 2004-03-21
	.- delete only <span> tag and leave <div> tag
.: 2004-03-20
	.- special macro BEGIN and END
	.- Ruby sanitizing
.: 2004-03-19
	.- new command option '--enable_eruby=true'
	.- new keyword 'empty'
	.- new action 'analyze'
	.- new directive notation 'id="foreach:item:list"'
.: 2004-03-13
	.- use id attribute instead of kd attribute.
	.- add description about new features
	   ({{,id="replace:{{/name/}}",}} and {{,:value({{/name/}}={{/expr/}}),}})
	.- add new samples (navilink, breadcrumbs, error messages, calendar)
.: 2004-03-08
	.- subsection 'Compare with null explicitly' added.
	.- some eratta fixed
.: 2004-02-27
	.- 'Notes' of directives and presentaion language updated
	.- description about sanitizing updated
.: 2004-02-24
	.- some eratta fixed
.: 2004-02-12
	.- public release
.#.: 2004-02-09 (Ver 0.4)
.#	.- widely changed.
.#
.#.: 2003-11-19 (ver 0.3)
.#	.- hugely changed.
.#
.#.: 2003-11-09 (ver 0.2)
.#	.- many changed.
.#
.#.: 2003-10-11 (ver 0.1)
.#	.- initial version




.$ About Kwartz		| intro


.$$ What's Kwartz?	| intro-whatis


Kwartz{{(Pronounced same as 'Quartz'.)}} is a template system, implemented in Ruby.
It has following features:


.%  Separate presentation logic from presentation data.
	
	Using any template system such as Velocity, XMLC, Amrita, etc,
	you can separate HTML desgin from business logic as a template.
	With Kwartz, you can separate presentation logic from a template.
	In other words, Kwartz divides a template into 'presentation data' and 'presentation logic'.
	You don't need to mix presentation logic into HTML file nor main program.
	.#In Kwartz, you can separate not only business logic but also presentation logic from HTML.
	
	
.%  Very fast
	
	Kwartz creates a script for the output from a template (= presentation data and presentaion logic). 
	.#(this action is called 'Compile').
	All you have to do in main program is to call the output script.
	Because Kwartz doesn't use DOM tree or so, Kwartz works very fast, and light-weight.
	
	
.%  Multi programing language
	
	Kwartz can create outputs script for Ruby, PHP, JSP and eRuby from a template file,
	because Kwartz uses an intermediate language internally.
	You don't have to change the presentation layer at all, even if you changed programming language.
	Kwartz supports the following language: Ruby, PHP, JSP, eRuby, ERB, Velocity
	
	
.%  Doesn't break HTML design at all
	
	You must use directives like '#foreach(...)' in
	{{<Jakarta Velocity|http://jakarta.apache.org/velocity/>}} or
	'[FOREACH ...]' in {{<Template-Toolkit|http://www.template-toolkit.org/>}}.
	These directives break HTML design of template.
	Kwartz doesn't break HTML design at all because Kwartz uses tag's attributes for marking in HTML template.
	
	
.%  Can handle any text file
	
	Kwartz uses an original template parser, not using XML parser,
	so as to enable to handle any text file (HTML, PostScript, RTF, and so on).
	It means that Kwartz can handle invalid-formed XML files, as well as well-formed XML files.
	It is an advantage of Kwartz against {{<Enhydra XMLC|http://xmlc.enhydra.org/>}} or
	{{<amrita|http://www.brain-tokyo.jp/research/amrita/index.html>}}, which handle only XML/HML files.
	
	
.%  Auto-Sanitizing Supported
	
	Kwartz can do sanitizing automatically.
	You don't need to write '{{,CGI.escapeHTML(var),}}' or '{{,htmlspecialchars($var),}}'.
	You are free to make sanitizing on/off, and can specify a certain part of template to sanitize or unsanitize.




.$$ Simple Example	| intro-example


In Kwartz, you should define a template as presentation data and presentation logic.
They are described in separate files.
.#This is a sample of presentation data file and presentation logic file.
.#You should create these two files.


This is a sample of presentation data file.
.* {{*{{,#{var}#,}}*}} means that "Output the value of variable 'var'."
.* {{*{{,id="xxx",}}*}} means that "I'll operate this element in presentation logic." (it is called 'marking').

Presentation data file(example.html):
.-------------------- example.html
<table>
  <tr {{*id="xxx"*}}>
    <td>{{*#{var}#*}}</td>
  </tr>
</table>
.--------------------


And the following is a sample of presentation logic.
In presentation logic, you can operate elements which are marked in presentation data.
.* {{*{{,:elem(xxx),}}*}} represents a element marked with name 'xxx' (= '<tr>...</tr>').
.* {{*{{,@stag,}}*}} represents a start tag (= '<tr>').
.* {{*{{,@cont,}}*}} represents a content(= '<td>#{user}#</td>').
.* {{*{{,@etag,}}*}} represents an end tag(= '</tr>').
.* {{*{{,:foreach(var=list) ... :end,}}*}} represents a iteration.
   In fact, this presentation logic re-define the marked element as to iterate from start tag to end tag.


Presentation logic file(example.plogic):
.-------------------- example.plogic
## Re-define an element to iterate start tag, content and end tag.
:elem(xxx)		## element
  :foreach(var=list)
    @stag		## start tag
    @cont		## content
    @etag		## end tag
  :end
:end
.--------------------


Kwartz creates output scripts automatically for Ruby, PHP, JSP, eRuby, ERB and Velocity from the above two files.
This action is called 'Compile'.
To compile, enter the following command:
.====================
### for Ruby
$ kwartz -l ruby  -p example.plogic example.html > example.rb
or
$ kwartz -l ruby2 -p example.plogic example.html > example.rb2

### for PHP
$ kwartz -l php   -p example.plogic example.html > example.php
or
$ kwartz -l php2  -p example.plogic example.html > example.php2

### for JSP
$ kwartz -l jsp   -p example.plogic example.html > example.jsp

### for eRuby
$ kwartz -l eruby -p example.plogic example.html > example.rthml

### for ERB
$ kwartz -l erb   -p example.plogic example.html > example.erb

### for Velocity
$ kwartz -l velocity -p example.plogic example.html > example.vm
.====================


The following is the output script for each language.

for Ruby (example.rb) :
	.--------------------
	.<<<:! ./kwartz -l ruby -p guide.d/example.plogic guide.d/example.html
	.--------------------
	
for Ruby (example.rb2) -- get output as string:
	.--------------------
	.<<<:! ./kwartz -l ruby2 -p guide.d/example.plogic guide.d/example.html
	.--------------------
	
for PHP (example.php) :
	
	.--------------------
	.<<<:! ./kwartz -l php -p guide.d/example.plogic guide.d/example.html
	.--------------------
	
for PHP (example.php2) -- get output as string:
	
	.--------------------
	.<<<:! ./kwartz -l php2 -p guide.d/example.plogic guide.d/example.html
	.--------------------
	
for JSP{{(if you specify a command line option '--charset={{/CHARSET/}}', kwartz will output {{,<%@ page contentType="text/html; charset={{/CHARSET/}}" %>,}} when JSP.)}}(example.jsp) :
	.--------------------
	.<<<:! ./kwartz -l jsp -p guide.d/example.plogic guide.d/example.html
	.--------------------
	
for eRuby(example.rhtml) :
	.--------------------
	.<<<:! ./kwartz -l eruby -p guide.d/example.plogic guide.d/example.html
	.--------------------
	
for ERB(example.erb) :
	.--------------------
	.<<<:! ./kwartz -l erb -p guide.d/example.plogic guide.d/example.html
	.--------------------
	
for Velocity(example.vm) :
	.--------------------
	.<<<:! ./kwartz -l velocity -p guide.d/example.plogic guide.d/example.html
	.--------------------


Using command-line option -s when compiling, kwartz will output sanitized scripts (except Velocity).
.#Currently, Ruby, PHP, JSP, eRuby and ERB are available with sanitizing.
For sanitizing, {{,htmlspecialchars(),}} is used in PHP, {{,CGI.escapeHTML(),}} in Ruby and eRuby, {{,html_escape(),}} in ERB, {{,<c:out/>,}} without {{,escapeXml="false",}} in JSP.


Then execute or import these output script in your main-program, like this:


Main program(ruby) :
	.--------------------
	require 'cgi'        # for sanitizing
	s = File.open('example.rb') { |f| f.read }
	s.untaint            # for CGI program
	eval s
	.--------------------
	
Main program(ruby2) :
	.--------------------
	require 'cgi'        # for sanitizing
	s = File.open('example.rb2') { |f| f.read }
	s.untaint            # for CGI program
	_s = ''
	eval s
	print _s
	.--------------------
	
Main program(php) :
	.--------------------
	<?php
	   include('example.php');
	 ?>
	.--------------------
	
Main program(php2) :
	.--------------------
	<?php
	   include('example.php2');
	   echo $_s;
	 ?>
	.--------------------
	
Main program (jsp) :
	.--------------------
	public void doGet(HttpServletRequest request,
	                  HttpServletResponse response)
	                  throws ServletException, IOException {
	   ...
	   RequestDispatcher dispatcher = 
	       request.getRequestDispatcher('example.jsp');
	   dispatcher.include(request, response);
	   // or dispatcher.forward(request, response);
	}
	.--------------------
	
Main program(eruby) :
	.--------------------
	require 'eruby'
	require 'cgi'        # for sanitizing
	ERuby::import('example.rhtml')
	.--------------------
	
Main program(erb) :
	.--------------------
	require 'erb'
	include ERB::Util    # for sanitizing
	s = File.open('example.erb') { |f| f.read }
	s.untaint            # for CGI program
	erb = ERB.new(s, $SAFE, '%')
	erb.run(binding())   # or print erb.result(binding())
	.--------------------
	
Main program(velocity) :
	.--------------------
	Velocity.init();
	VelocityContext context = new VelocityContext();
	Template template = Velocity.getTemplate("example.vm");
	OutputStreamWriter writer = new OutputStreamWriter(System.out);
	template.merge(context, writer);
	writer.flush();
	.--------------------


Calling or executing output scripts, you can get web page like this:

.____________________
<table>
  <tr id="xxx">
    <td>apple</td>
  </tr>
  <tr id="xxx">
    <td>orange</td>
  </tr>
  <tr id="xxx">
    <td>banana</td>
  </tr>
</table>
.____________________



You may mind that id attributes are appeared in each <tr></tr>.
You can delete it from web page if you write it as {{,id="mark:xxx",}}
(which is equivalent to {{,id="xxx",}} but it removes id attribute itself),
or add command line option {{,--delete_idattr=true,}}.




In addition, you can 'embed' presentation logic into presentation data in Kwartz.
You can select to separate or not to sepearate presentation data and presentation logic.


To embed presentation logic into presentation data, use directives.
Directive is a command to embed presentation logic into presentation data.
In Kwartz, 'id' or 'kd' attributes are used to describe directives.


The following is a sample of 'embedding' presentation logic into presentation data.
This sample is compiled into the same output as the script files in above.
.
.-------------------- example2.html
<table>
  <tr {{*id="foreach:var=list"*}}>
    <td {{*id="value:var"*}}>foo</td>
  </tr>
.#  <tr {{*id="dummy:d1"*}}>
.#    <td>bar</td>
.#  </tr>
</table>
.--------------------




.$ How Kwartz works		| detail


.$$ Presentation data		| detail-pdata


Kwartz separates presentation layer into 'presentation data' and 'presentation logic' with the following approach.
.* In presentation data, mark a part which you will operate.
   You should use {{,id="{{/name/}}",}} to mark.
.* In presentation logic, operate a part which is marked.


It is called 'marking' to mark a region which you want to change or replace in the presentation data.
You can do 'marking' with attribute 'id' or 'kd'{{(The attribute name is derived from 'Kwartz Directive'. You can change the name of attribute with command-line option --attr_name.)}}, like {{,id="{{/name/}}",}}.


Example of marking:
.--------------------
<table>
 <tr {{*id="list"*}}>
  <td>#{item}#</td>
 </tr>
</table>
.--------------------


Kwartz recognizes only marked elements, and regard unmarked elements as a normal plain texts.
It means that Kwartz can handle any type of text, including not well-formed XML file. 


Example of 'not well-formed XML file':
.--------------------
<span id="test">
 aaa <bbb> ccc </ddd>
</span>
.--------------------




.$$ Intermediate code		| detail-intermed


Kwartz 'converts' presentation data into intermediate code.


When converting a presentation data into intermeidate code, Kwartz creates four macros for each marked elements.
.* macro 'sttag_{{/xxx/}}' represents a start-tag.
.* macro 'cont_{{/xxx/}}' represents contents.
.* macro 'etag_{{/xxx/}}' represents a end-tag.
.* macro 'elem_{{/xxx/}}' represents an element, which is constructed with start-tag, contents and end-tag.


Here is a sample of presentation data:
.--------------------
<table>
 <tr id="list">
  <td>#{item}#</td>
 </tr>
</table>
.--------------------

Kwartz will convert the presentation data into the following intermediate code.
You'll find that four macros are defined and presentation data is described with these macros.

.--------------------
:macro(stag_list)          ## start tag
  :print(" <tr id=\"list\">\n")
:end

:macro(cont_list)          ## content
  :print("  <td>", item, "</td>\n")
:end

:macro(etag_list)          ## end tag
  :print(" </tr>\n")
:end

:macro(elem_list)          ## element
  :expand(stag_list)            ## expand a macro
  :expand(cont_list)            ## expand a macro
  :expand(etag_list)            ## expand a macro
:end

:print("<table>\n")        ## presentation data
:expand(elem_list)              ## expand macro
:print("</table>\n")
.--------------------


'{{,id="list",}}' will be left in intermediate code.
If you want to delete it, use '{{,id="mark:list",}}' instead, or add command line option {{,--delete_idattr=true,}}


Intermediate code is described in an itermediate language.
The language is named 'PL'(Presentation Language).



.$$ Presentation Logic			| detail-plogic


Presentation logic is:
.* Described in PL(Presentation Language), which is used as intermediate language.
.* Described as a macro to overwrite the macro-definition which is automatically generated.


The following is a sample of presentation logic.
This sample will overwrite macro 'elem_list' to iterate from start tag to end tag.
.--------------------
:macro(elem_list)
  :foreach(item=itemlist)    ## iteration with foreach statement
    :expand(stag_item)       ## start tag
    :expand(cont_item)       ## content
    :expand(etag_item)       ## end tag
  :end
:end
.--------------------


And you can write the above presentation logic as the following.
Kwartz parser will treat it as the same code as the above.
.--------------------
:elem(list)                  ## same as :macro(elem_item) 
  :foreach(item=itemlist)
    @stag                    ## same as :expand(stag_item)
    @cont                    ## same as :expand(cont_item)
    @etag                    ## same as :eppand(etag_item)
  :end
:end
.--------------------




.$$ Output script		| detail-outscript


Kwartz merges intermediate code and presentation logic, then expands macros and transforms it into an output script.
This action is called 'translation'.


This is a sample of translation.

.____________________
   
   :print("<table>\n")
   :expand(elem_list)
   :print("</table>\n")

      |
      | expand macros
      V

   :print("<table>\n")
   {{*:foreach(item=itemlist)*}}
     {{*:expand(stag_list)*}}
     {{*:expand(cont_list)*}}
     {{*:expand(etag_list)*}}
   {{*:end*}}
   :print("</table>\n")

      |
      | expand macros
      V

   :print("<table>\n")
   :foreach(item=itemlist)
     {{*:print(" <tr id=\"list\">\n")*}}
     {{*:print("  <td>", item, "</td>\n")*}}
     {{*:print(" </tr>\n")*}}
   :end
   :print("</table>\n")

      |
      | output script for each langague
      V

   ### for Ruby
   print "<table>\n"
   for item in itemlist do
     print " <tr id=\"list\">\n"
     print "  <td>", item, "</td>\n"
     print " </tr>\n"
   end
   print "</table>\n"
 
   ### for PHP
   <table>
   <?php foreach($itemlist as $item) { ?>
    <tr id="list">
     <td><?php echo $item; ?></td>
    </tr>
   <?php } ?>
   </table>

   ### for JSP
   <table>
   <c:forEach var="item" items="${itemlist}">
    <tr id="list">
     <td><c:out value="${item}"/></td>
    </tr>
   </c:forEach>
   </table>

   ### for eRuby
   <table>
   <% for item in itemlist do
    %> <tr id="list">
     <td><%= item %></td>
    </tr>
   <% end
    %></table>

   ### for ERB
   <table>
   % for item in itemlist do
    <tr id="list">
     <td><%= item %></td>
    </tr>
   % end
   </table>

   ### for Velocity
   <table>
   #foreach ($item in $itemlist)
    <tr id="list">
     <td>${item}</td>
    </tr>
   #end
   </table>

.____________________


The remarking task is to call or execute these output scripts in main program.


These are the all what Kwartz does.



.$$ How to call or execute output script	| detail-import


The way to call or execute output script is different for each language.
See other documents for detail.


.%  in Ruby:
	Read and eval output file. You have to require cgi.rb when sanitiginz.
	.--------------------
	require 'cgi'         # for sanitizing
	str = File.open('example.rb') { |f| f.read }
	str.untaint           # for CGI program
	eval str
	.--------------------
	Or if you specified command line option `{{,-l ruby2,}}' :
	.--------------------
	require 'cgi'         # for sanitizing
	str = File.open('example.rb') { |f| f.read }
	str.untaint           # for CGI program
	_s = ''
	eval str
	print _s
	.--------------------

.%  in PHP:
	Use include() function.
	.--------------------
	<?php include('example.phtml'); ?>
	.--------------------
	Or if you specified command line option `{{,-l php2,}}' :
	.--------------------
	<?php include('example.phtml'); echo $_s; ?>
	.--------------------

.%  in JSP (Servlet):
	Use RequestDispatcher#forward() or RequestDispatcher#include().
	.--------------------
	RequestDispatcher dispatcher = 
	    request.getRequestDispatcher("example.jsp");
	dispatcher.forward(request, response);
	.--------------------

.%  in eRuby:
	Use ERuby::import() when using eruby. You have to require cgi.rb when sanitiginz.
	.--------------------
	require 'eruby'
	require 'cgi'         # for sanitizing
	ERuby::import('example.rhtml')
	.--------------------

.%  in ERB:
	Use ERB#run() when using ERB.
	You should specify '%' as trim parameter when creating ERB object.
	And you have to impoort {{,ERB::Util,}} when sanitizing.
	.--------------------
	require 'erb'
	include ERB::Util     # for sanitizing
	str = File.open('example.erb') { |f| f.read }
	str.untaint
	erb = ERB.new(str, $SAFE, '%')
	erb.run(binding())   # or print erb.result(binding())
	.--------------------

.%  in Velocity:
	Use org.apache.velocity.context.Context, org.apache.velocity.Template, and so on.
	See Velocity's manual for details.
	.--------------------
	Velocity.init();
	VelocityContext context = new VelocityContext();
	Template template = Velocity.getTemplate("example.vm");
	OutputStreamWriter writer = new OutputStreamWriter(System.out);
	template.merge(context, writer);
	writer.flush();
	.--------------------




.$$ Other examples of presentation logic	| detail-appl


An example described in the previous section is to iterate from start tag to end tag.
This section shows some other examples.


.#.* To print out value of variabe instead of content, overwrite a macro 'cont_{{/xxx/}}'.
.#   You can reduce '{{,#{var}#,}}' in this way.
.#	.--------------------
.#	:macro(cont_list)
.#	  :print(item)        ## original is :print('foo')
.#	:end
.#	.--------------------

.* You can iterate only contents. This is useful for <dl></dl>.
	.--------------------
	:macro(elem_list)
	  :expand(stag_list)
	  :foreach(item=itemlist)
	    :expand(cont_list)
	  :end
	  :expand(etag_list)
	:end
	.--------------------
	or
	.--------------------
	:elem(list)
	  @stag
	  :foreach(item=itemlist)
	    @cont
	  :end
	  @etag
	:end
	.--------------------

.* You can print a value of variable or expression instead of a static content string.
	.--------------------
	:macro(elem_list)
	  :expand(stag_list)
	  :print(item['key'])
	  :expand(etag_list)
	:end
	.--------------------
	or
	.--------------------
	:elem(list)
	  @stag
	  :print(item['key'])
	  @etag
	:end
	.--------------------

.* You can print a value of variable or expression instead of element.
	.--------------------
	:macro(elem_list)
	  :print(item['key'])
	:end
	.--------------------
	or
	.--------------------
	:elem(list)
	  :print(item['key'])
	:end
	.--------------------

.* You can replace an element with other macro.
	.--------------------
	:macro(elem_list)
	  :expand(other_macro)
	:end
	:macro(other_macro)
	  :print('...')
	  :print('...')
	:end
	.--------------------
	or
	.--------------------
	:elem(list)
	  :expand(other_macro)
	:end
	:macro(other_macro)
	  :print('...')
	  :print('...')
	:end
	.--------------------

.* You can delete start tag and end tag when you comment out them.
	.--------------------
	:macro(elem_list)
	  ## :expand(stag_list)
	  :expand(cont_list)
	  ## :expand(etag_list)
	:end
	.--------------------
	or
	.--------------------
	:elem(list)
	  ## @stag
	  @cont
	  ## @etag
	:end
	.--------------------

.* You can delete an element. It is useful for delete dummy data.
	.--------------------
	:macro(elem_list)
	  ## :expand(stag_list)
	  ## :expand(cont_list)
	  ## :expand(etag_list)
	:end
	.--------------------
	or
	.--------------------
	:elem(item)
	  ## @stag
	  ## @cont
	  ## @etag
	:end
	.--------------------

.* You can include a complex presentation logic like this:
	.--------------------
	:macro(elem_list)
	  :set(ctr = 0)
	  :foreach(item=itemlist)
	    :set(ctr += 1)
	    :set(color = ctr%2==0 ? 'red' : 'blue')
	    :expand(stag_item)
	    :expand(cont_item)
	    :expand(etag_item)
	  :end
	:end
	.--------------------
	or
	.--------------------
	:elem(list)
	  :set(ctr = 0)
	  :foreach(item=itemlist)
	    :set(ctr += 1)
	    :set(color = ctr%2==0 ? 'red' : 'blue')
	    @stag
	    @cont
	    @etag
	  :end
	:end
	.--------------------


It is very important that tag/attribute names don't appear in presentation logic at all.
In other words, you don't need to change presentaion logic files even if the tag/attribute name is changed in the presesntation data.


It means that Kwartz separates presentation logic from presentation data.




.$$ Conclution		| detail-conc


This is a chart of a process which represents how Kwartz works.
In this chart, with '*' represents a file which is created automatically,
Without '*' represents a file which have to be created manually by a developer.

.____________________
  Presentation Data           Presentation Logic
    (HTML)                    (intermediate language)
       |                            |
       | convert                    |
       |                            |
       V                            |
Intermediate Code*                  |
(intermediate language)             |
       |                            |
       |                            |
       +-------------+--------------+
                     | translate
                     |
                     V              call/import
              Output Program*    <============ Main Program
           (Ruby/PHP/JSP/eRuby)             (Ruby/PHP/JSP/eRuby)
                     |
                     | output
                     |
                     V
                 Web Page*
                  (HTML)
.____________________


Following files are created by a developer manually:
.* presentation data file (HTML file)
.* presentation logic file
.* main program


Kwartz creates automatically:
.* intermediate code
.* output script
.* web page


Term:
.[convert]
	To transform presentation data into intermediate code
.[translate]
	To transform intermeidate code and presentation logic into output script.
.[compile]
	'Convert' and 'translate', that is, transform presentation data and presenstaion logics into an output script.




.$ Directive		| directive


.$$ What is directive?	| directive-whatis


Kwartz allows presentation logics to embedded in presentation data.
Commands for that purpose is called 'directive'.


'Directive' is a set of commands to embed presentation logics into presentation data.
Marking ({{,id="{{/name/}}",}} or {{,id="mark:{{/name/}}",}}) is also directive.
There are several directives for iteration, conditional branch, and so on.


Kwartz uses 'id' or/and 'kd' attribute to embed directives in presentation data ('kd' means 'Kwartz Directive').
Usually id attribute is used, but if you want to use id attribute for other purpose you can use kd attribute instead of id attribute.
And you can use both id and kd attribute in a tag.
See '{{<Id and kd attributes|#directive-idkd>}}' for detail about id and kd attribute.


You may have a question: 
It is the most important feature of Kwartz that Kwartz separates presentation logics from presentation data.
Why does Kwartz allow to embed presentation logics into presentation data? 


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


You may wonder that Kwartz becomes a ordinary template system if presentation logic is embedded into presentation data.
But Kwartz has the following merits compared to other template system.
.* Kwartz doesn't break HTML design. Compare to {{<Jakarta Velocity|http://jakarta.apache.org/velocity/>}} or {{<Template-Toolkit|http://www.template-toolkit.org/>}}.
.* Kwartz doesn't need comprex programming. Compare to {{<Enhydra XMLC|http://xmlc.objectweb.org/>}}, which needs complex DOM programming.
.* Kwartz works very fast and light-weight. Compared to {{<amrita|http://www.brain-tokyo.jp/research/amrita/index.html>}}.
.* Kwartz can handle any type of text. Compare to Enhydra {{<XMLC|http://xmlc.objectweb.org/>}} or {{<amrita|http://www.brain-tokyo.jp/research/amrita/index.html>}}.
.* Kwartz can be used in several language. There is no other template system like this!.




.$$ Marking	| directive-mark


Directive {{,id="{{/name/}}",}} or {{,id="mark:{{/name/}}",}} marks an element.
'Marking' is to mark an element with a name {{,{{/name/}},}}.
The marked element is described as a macro in intermediate code.



Presentation Data:
.-------------------- directive-mark.html
<li {{*id="item"*}}>foo</li>
.--------------------

Intermediate Code:
.____________________
.<<<:! kwartz -a convert guide.d/directive-mark.html
.____________________

Output Program:
.____________________
.<<<:! ruby output.rb guide.d/directive-mark.html
.____________________



The difference between '{{,id="{{/name/}}",}}' and '{{,id="mark:{{/name/}}",}}' is that the former is leaved but the latter is removed when compiling into intermediate code.



Presentation Data:
.-------------------- directive-mark2.html
<li {{*id="mark:item"*}}>foo</li>
.--------------------

Intermediate Code:
.____________________
.<<<:! kwartz -a convert guide.d/directive-mark2.html
.____________________



.$$ Print value of expression | directive-output

{{,#{/expression/}#,}} is a directive which prints the value of expression.
It is equivarent to 'print {{/expression/}}' in Ruby, or '<?php echo {{/expression/}}; ?>' in PHP.

Presentation Data:
.-------------------- directive-output.html
Hello {{*#{user}#*}}!
.--------------------

Intermediate Code:
.____________________
:print("Hello ", {{*user*}}, "!\n")
.____________________

Output Program:
.____________________
.<<<:! ruby output.rb guide.d/directive-output.html
.____________________


Expression is sanitized if you specified command option {{,-s,}} (or {{,--escape=true,}}) when compiling template.
Notice that only expressions except constant string and constant number are sanitized.

Output Program (with command option {{,-s,}}) :
.____________________
.<<<:! ruby output.rb -s guide.d/directive-output.html
.____________________



Using function {{,E(),}} or {{,X(),}}, you can specify sanitizing on/off for each expressions.
{{,E({{/expr/}}),}} means that expression expr is sanitized and {{,X({{/expr/}}),}} means that expr is not sanitized.
These are not effected by command option {{,-s,}} (or {{,--escape=true,}}).

Presentation Data:
.-------------------- directive-output2.html
With sanitizing:    {{*#{E(expr)}#*}}!
Without sanitizing: {{*#{X(expr)}#*}}!
.--------------------

Intermediate Code:
.____________________
:print("With sanitizing:    ", {{*E(expr)*}}, "\n")
:print("Without sanitizing: ", {{*X(expr)*}}, "\n")
.____________________

Output Program:
.____________________
.<<<:! ruby output.rb guide.d/directive-output2.html
.____________________



.$$ Print value of expression 2| directive-value

{{,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 to use dummy data.

Presentation Data:
.-------------------- directive-value.html
<li {{*id="value:hash['name']"*}}>foo</li>
.--------------------

Intermediate Code:
.____________________
:print("<li>", {{*hash['name']*}}, "</li>\n")
.____________________

Output Program:
.____________________
.<<<:! ruby output.rb guide.d/directive-value.html
.____________________


Using {{,id="Value:{{/expr/}},}}, you can specify to sanitize expression.
And using {{,id="VALUE:{{/expr/}},}}, you can specify not to sanitize expression.
These are equal to {{,id="value:E({{/expr/}}),}} or {{,id="value:X({{/expr/}}),}}.




.$$ Attribute value	| directive-attr

{{,id="attr:{{/name/}}={{/value/}}",}} (or {{,id="attr:{{/name/}}:{{/value/}}",}}) is a directive to set an attribute value.
It overwrites existing value if attribute {{/name/}} is setted.

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

Presentation Data:
.-------------------- directive-attr.html
<tr class="odd" {{*id="attr:class=klass"*}}>
  <td>foo</td>
</tr>
.--------------------

Intermediate Code:
.____________________
:print("<tr class=\"", {{*klass*}}, "\">\n")
:print("  <td>foo</td>\n")
:print("</tr>\n")
.____________________

Output Program:
.____________________
.<<<:! ruby output.rb guide.d/directive-attr.html
.____________________


Using {{,id="Attr:{{/name/}}={{/value/}},}}, you can specify to sanitize value.
And using {{,id="ATTR:{{/name/}}={{/value/}},}}, you can specify not to sanitize value.
These are equal to {{,id="attr:{{/name/}}=E({{/value/}}),}} or {{,attr:{{/name/}}=X({{/value/}}),}}.


Separating with '{{,;,}}', you can list several {{,attr:{{/name/}}={{/value/}},}} directives in one id attribute,
or list with other directive.

Presentation Data:
.-------------------- directive-attr2.html
<font id="if:message{{*;attr:class=klass;attr:bgcolor=color*}}">
 #{message}#
</font>
.--------------------

Intermediate Code:
.____________________
:if(message)
  :print("<font class=\"", {{*klass*}}, "\" bgcolor=\"", {{*color*}}, "\">\n")
  :print(" ", message, "\n")
  :print("</font>\n")
:end
.____________________

.#Output Program:
.#.____________________
.#.<<<:! ruby output.rb guide.d/directive-attr2.html
.#.____________________



.$$ Assign	| directive-set

{{,id="set:{{/var/}}={{/value/}},}} (or {{,id="set:{{/var/}}:{{/value/}},}}) is directive for assigning value into a variable.
Not only '{{,=,}}' but also '{{,+=,}}', '{{,-=,}}', '{{,*=,}}', '{{,/=,}}', '{{,.+=,}}' are available.
('{{,.+=,}}' means string concatination.)

Presentation Data:
.-------------------- directive-set.html
<dt {{*id="set:var=value"*}}>foo</dt>
<dd {{*id="set:count+=1"*}}>123</dd>
.#<tr class="#{klass}#" {{*id="set:klass=ctr%2==0?'even':'odd'"*}}>
.#  <td>foo</td>
.#</tr>
.--------------------

Intermediate Code:
.____________________
{{*:set(var=value)*}}
:print("<dt>")
:print("foo")
:print("</dt>\n")
{{*:set(count+=1)*}}
:print("<dd>")
:print("123")
:print("</dd>\n")
.#{{*:set(klass=ctr%2==0?'even':'odd')*}}
.#:print("<tr class=\"", klass, "\">\n")
.#:print("  <td>foo</td>\n")
.#:print("</tr>\n")
.____________________

Output Program:
.____________________
.<<<:! ruby output.rb guide.d/directive-set.html
.____________________



.$$ Conditional branch	| directive-if

{{,id="if:{{/expression/}}",}} is a directive for conditional branch.
It enables only if-statement, cannot represent 'else' or 'else if'.
If you want to use 'else' or 'else if', you should describe then in presentation logic file.

Presentation Data:
.-------------------- directive-if.html
<font color="red" {{*id="if:flag_error"*}}>
 Error!!
</font>
.--------------------

Intermediate Code:
.____________________
{{*:if(flag_error)*}}
  :print("<font color=\"red\">\n")
  :print(" Error!!\n")
  :print("</font>\n")
{{*:end*}}
.____________________

Output Program:
.____________________
.<<<:! ruby output.rb guide.d/directive-if.html
.____________________



.$$ Iteration(foreach)	| directive-foreach

{{,id="foreach:{{/var/}}={{/list/}}",}} (or {{,id="foreach:{{/var/}}={{/list/}}",}}) is a directive for iteration, with assignment each value of list into a variable.
.#Start tag, contents and end tag are iterated.

Presentation Data:
.-------------------- directive-foreach.html
<tr {{*id="foreach:user=user_list"*}}>
  <td>#{user}#</td>
</tr>
.--------------------

Intermediate Code:
.____________________
{{*:foreach(user = user_list)*}}
  :print("<tr>\n")
  :print("  <td>", user, "</td>\n")
  :print("</tr>\n")
{{*:end*}}
.____________________

Output Program:
.____________________
.<<<:! ruby output.rb guide.d/directive-foreach.html
.____________________



.$$ Iteration(list)	| directive-list

{{,id="list:{{/variable/}}={{/list_expr/}}",}} (or {{,id="list:{{/variable/}}:{{/list_expr/}}",}}) is a directive for iteration.
It iterates only contents. Start tag and end tag are not iterated.

Presentation Data:
.-------------------- directive-list.html
<tr {{*id="list:user=user_list"*}}>
  <td>#{user}#</td>
</tr>
.--------------------

Intermediate Code:
.____________________
:print("<tr>\n")
{{*:foreach(user = user_list)*}}
  :print("  <td>", user, "</td>\n")
{{*:end*}}
:print("</tr>\n")
.____________________

Output Program:
.____________________
.<<<:! ruby output.rb guide.d/directive-list.html
.____________________



.$$ Iteration with count	| directive-foreach2


{{,id="Foreach:{{/var/}}={{/list/}}",}} and {{,id="List:{{/var/}}={{/list/}}",}} are directives for iteration with loop counting.
Counter variable name is {{,{{/var/}}_ctr,}}.  Counter starts with 1.


Presentation Data:
.-------------------- directive-foreach2.html
<tr {{*id="Foreach:item=item_list"*}}>
  <td id="value:item_ctr">1</td>
  <td id="value:item">foo</td>
</tr>
.--------------------

Intermediate Code:
.____________________
{{*:set(item_ctr = 0)*}}
{{*:foreach(item = item_list)*}}
  {{*:set(item_ctr += 1)*}}
  :print("<tr>\n")
  :print("  <td>", item_ctr, "</td>\n")
  :print("  <td>", item, "</td>\n")
  :print("</tr>\n")
{{*:end*}}
.____________________

Output Program:
.____________________
.<<<:! ruby output.rb guide.d/directive-foreach2.html
.____________________




.$$ Iteration with toggle switch	| directive-foreach3


{{,id="FOREACH:{{/var/}}={{/list/}}",}} and {{,id="FOREACH:{{/var/}}={{/list/}}",}} are directives for iteration with toggle-switching.
Toggle-switch's value is changed if loop counter is odd or even.
Variable Name of toggle-switch is {{,{{/var/}}_tgl,}}.
Value of toggle-switch is {{,'odd',}} and {{,'even',}} by default.
You can change them with command-line option --odd_value and --even_value.


Presentation Data:
.-------------------- directive-foreach3.html
<table>
  <tbody {{*id="LIST:item=item_list"*}}>
    <tr class="#{item_tgl}#">
      <td id="value:item">foo</td>
    </tr>
  </tbody>
</table>
.--------------------

Intermediate Code:
.____________________
:print("<table>\n")
:print("  <tbody>\n")
{{*:set(item_ctr = 0)*}}
{{*:foreach(item = item_list)*}}
  {{*:set(item_ctr += 1)*}}
  {{*:set(item_tgl = item_ctr % 2 == 0 ? 'even' : 'odd')*}}
  :print("    <tr class=\"", item_tgl, "\">\n")
  :print("      <td>", item, "</td>\n")
  :print("    </tr>\n")
{{*:end*}}
:print("  </tbody>\n")
:print("</table>\n")
.____________________

Output Program:
.____________________
.<<<:! ruby output.rb guide.d/directive-foreach3.html
.____________________




.$$ Iteration (while)	| directive-while


{{,id="while:{{/expression/}}",}} is a directive to iterate, with while-statement. 
Assignment is not expression in Kwartz, except in while-condition.


Kwartz will cause error when compiling while-statemnt into JSP or Velocity,
because there is no custom tags in JSTL or Velocity's directive which is equvalent to while-statment.


Presentation Data:
.-------------------- directive-while.html
<tr {{*id="while:row=sth.fetch"*}}>
  <td>#{row[0]}#</td>
</tr>
.--------------------

Intermediate Code:
.____________________
{{*:while(row=sth.fetch)*}}
  :print("<tr>\n")
  :print("  <td>", row[0], "</td>\n")
  :print("</tr>\n")
{{*:end*}}
.____________________

Output Program:
.____________________
.<<<:! ruby output.rb -l ruby,php,eruby,erb guide.d/directive-while.html
.____________________



.$$ Dummy data	| directive-dummy

{{,id="dummy:{{/name/}}",}} is a directive fore ignoring an element.
You should specify a unique string{{(The string have no effectivity nor meaning.)}} in {{,{{/name/}},}}.
{{/name/}} is a string to make different id attribute value in a XML/HTML document.
You cannot specify same string in a document.

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 Element	| directive-replace


'{{,id="replace:{{/name/}}",}}' replaces an element with other element which is marked with name {{/name/}}.

Presentation Data:
.-------------------- directive-replace.html
<html>
  <body>
    <!-- breadclumbs navigation -->
    <span {{*id="breadclumbs"*}}>
      <a href="/">Home</a>
      &gt; <a href="/ruby">Ruby</a>
      &gt; <a href="/ruby/kwartz">Kwartz</a>
    </span>

   ....

    <span {{*id="replace:breadclumbs"*}}>
      Home &gt; Ruby &gt; Kwartz
    </span>
  </body>
</html
.--------------------

Intermediate Code:
.____________________
.<<<:! ruby output.rb -a convert guide.d/directive-replace.html
.____________________



.$$ Include presentation data file		| directive-include


{{,id="include:'{{/filename/}}'",}} directive reads and includes other presentation data file (HTML file).
Usually, {{,<span/>,}} tag is used such as {{,<span id="include:'{{/filename/}}'"/>,}}.	
(In Kwartz, {{,<span>,}} tags which contain only directives are deleted automatically.)


Presentation Data(tab.html) :
.-------------------- tab.html
<span style="border-width:1 1 0 1; border-style:solid; padding:1 5 1 5">
  <a href="#{tab['url']}#" id="value:tab['name']" style="text-decoration:none">TabName</a>
</span>
.--------------------

Presentation Data(tab-main.html) :
.-------------------- tab-main.html
<div id="foreach:tab:tablist">
  <span {{*id="include:'tab.html'"*}}/>
</div>
.--------------------

Intermediate Code:
.____________________
.<<<:! kwartz -a convert --include_path=guide.d guide.d/tab-main.html
.____________________


Presentation data files included are to be placed in other directory.
You can specify directories with a command line option {{,--include_path={{/dir1/}},{{/dir2/}},...,}}.

.====================
$ kwartz --include_path=dir1,dir2 tab-main.html
.====================




.$$ Load presentation logic file		| directive-load


{{,id="load:'{{/filename/}}'",}} directive reads and includes other presentation data file (HTML file).
Usually, {{,<span/>,}} tag is used such as {{,<span id="load:'{{/filename/}}'"/>,}}.	
(In Kwartz, {{,<span>,}} tags which contain only directives are deleted automatically.)


Usually, file name of presentation logic is specified by command line option({{,-p,}} or {{,-P,}}).
{{,load,}} directive is equal to these comamnd line options.
In other words, you can specify file name of presentation logic with {{,load,}} directive as well as command line options.
And {{,load,}} directive is avairable with command line options.

{{,load,}} directive should be at the end of presentation data file.
Otherwise, presentation logic loaded may be overwritten by presentation data file.


Presentation Logic (load-lib.plogic) :
.-------------------- load-lib.plogic
:elem(item)
  :foreach(item=itemlist)
    @stag
    @cont
    @etag
  :end
:end

:macro(BEGIN)
  :print("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n")
  :print("<html lang=\"en\">\n")
  :print(" <body bgcolor=\"#FFFFFF\">\n")
:end

:macro(END)
  :print(" </body>\n")
  :print("<html>\n")
:end
.--------------------

Presentation Data(load-main.html) :
.-------------------- load-main.html
<ul id="mark:itemlist">
  <li id="value:item">foobar</li>
</ul>
<span {{*id="load:'load-lib.plogic'"*}}/>
.--------------------

Intermediate Code:
.____________________
.<<<:! kwartz -a convert --load_path=guide.d guide.d/load-main.html
.____________________

Output Program:
.____________________
.<<<:! ruby output.rb --load_path=guide.d guide.d/load-main.html
.____________________


Presentation data files loaded are to be placed in other directory.
You can specify directories with a command line option {{,--load_path={{/dir1/}},{{/dir2/}},...,}}.

.====================
$ kwartz --load_path=dir1,dir2 load-main.html
.====================





.$$ Id and kd attributes	| directive-idkd




.* Kd attribute is equivalent to id attribute in Kwartz.
   All what you write in id attribute is able to be in kd attribute.


.* If a tag has both id attribute and kd attribte, Kwartz puts the latter before the former.
   For example, if you write '{{,id="name" kd="foreach:item=list",}}', kd attribute is enabled but not id attribute.


.* However, if kd attribute has only {{,attr,}} directives, then id attribute is enabled.
   For example, if you write '{{,id="name" kd="attr:href=url",}}, the element is marked with a name {{,name,}}.


.* HTML Specification defines that id attribute value can contain only alphabet, number, underbar({{,_,}}), colon({{,:,}}), hyphen({{,-,}}) and period({{,.,}}) (in ASCII character). 
   Other characters cannot be in id attribute value.
   It means that {{,id="foreach:item=list",}} or {{,id="attr:name=value",}} are not valid in HTML specification.
   It is recommended to write {{,id="foreach:item:list",}} or {{,id="attr:name:value",}} instead.
   .#It means that {{,id="foreach:item=list",}} or {{,id="value:item['user'],}} is not valid in HTML specification.
   .#You should remember it.


.* Kd attribte is Kwartz original and it is not in HTML specification.
   So, you gets errors when you use {{<W3C Markup Vaidation Service|http://validator.w3.org>}} with HTML files which contain kd attributes.
   Kwartz gives you a CGI/PHP script which delete kd attribute from your HTML file and send it to {{<W3C Markup Vaidation Service|http://validator.w3.org>}}.
   They are included in Kwartz archive, and avaialble at {{<here|<http://www.kuwata-ab.com/webtech/kwartz/validator.php>}}.


.* You can change kd attribte name with command line option {{,--attr_name={{/xxx/}},}}.
   For example, {{,--attr_name=style,}} make kwartz to use style attributes instead of kd attributes.




.$$ Notes	| directive-notes


There are some notes to use directives.


.* One id or kd 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">???</span>
	.--------------------


.* However, {{,attr,}} directive can be used with other directive in a kd attribute,
   and multiple attr directive can be in a kd attribute.
.#   For example, '{{,id="foreach:var=list;attr:class=var.class;attr:href=var.href",}}' is OK.
	.--------------------
	## OK
	<foo id="foreach:var=list;attr:class=var.class;attr:href=var.href">
	....
	</foo>
	.--------------------


.* You cannot ommit end-tag when using Kwartz directive.
   You can use empty-element tag, such as '{{,<foo .../>,}}'.
	.--------------------
	## NG
	<ul>
	  <li id="value:item">foo
	</ul>
	## OK
	<a id="attr:name=refname"/>
	.--------------------


.* Tag <span></span> tag is deleted if it have only directives.
   For example, presentation data '{{,Hello <span id="value:name">World</span>!,}}' will be converted into intermediate code '{{,:print('Hello ' .+ name .+ '!'),}}', with deleting <span></span>.
	.--------------------
	## presentation data
	Hello <span id="value:name">World</span>!
	## intermediate code
	:print("Hello ")
	:print(name)
	:print("!\n")
	.--------------------


.* You must describe attributes like {{,{{/attr/}}="{{/value/}}",}} in start tag which contains Kwartz directives.
   In other words, you cannot omit attribute name or attribute value 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=item.value" #{item.selected ? 'selected' : ''}#/>
	## OK
	<option value="#{item.value}#" #{item.selected ? 'selected' : ''}#>
	.--------------------


.* A directive which contains a character '{{,>,}}' will be failed to compile.
   For example, '{{,<span id="while:i>0">,}}' will be failed to compile.
   You should write it as '{{,<span id="while:0<i">,}}'. .^
   Kwartz parses a presentation data with regular expression matching.
   Therefore, '{{,<span id="while:i>0">,}}' will be parsed as '{{,<span id="while:i>,}}' and '{{,0">,}}',
   and covertion will be fail.
	.--------------------
	<span id="while:i>0"> ... </span>         ## NG
	<span id="while:0<i"> ... </span>         ## OK
	.--------------------


.* '{{,id="set:var=flag?v1:v2",}}' or '{{,id="value:flag?v1:v2",}}' will cause syntax error,
   because kwartz recognize '{{,:v2,}}' as beginning of statement (like '{{,:print,}}' or '{{,:if,}}').
   You should cover '{{,:v2,}}' with '{{,(),}}' or insert a space between '{{,:,}}' and '{{,v2,}}'.
	.--------------------
	<span id="set:var=flag?v1:v2"/>          ## NG
	<span id="set:var=flag?v1:(v2)"/>        ## OK
	<span id="set:var=flag?v1: v2"/>         ## OK
	.--------------------




.$ PL -- Presentation Language	| pl


Kwartz uses intermeidate language internally.
The intermediate language is named PL(Presentation Language).
PL is used for two purpose in Kwartz:
.* To describe intermediate code (which is automatically generated from presentation data)
.* To describe presentation logic


In fact, Kwartz describe presentation data and presentation logic in PL.


This section shows how to write PL program.



.$$ Comment	| pl-comment

Characters coming after '{{,#,}}' in a line is a comment.
You should use '{{,##,}}' instead of '{{,#,}}',
because '{{,#*,}}' or '{{,#@,}}' may have special functions in the future.

.--------------------
## comment
.--------------------



.$$ String | pl-string


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

.--------------------
'foo bar'		## String
"foo bar\n"		## String which contains line feed character
.--------------------



.$$ Boolean and null | pl-boolean


Keywords {{,true,}}, {{,false,}}, {{,null,}} are available in expression.

.--------------------
:set(flag = obj == null? true : false)
.--------------------


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

.+--------------------
Language name	., true		., false	., null
.--------------------
Ruby,eRuby,ERB	., true		., false	., nil
PHP		., TRUE		., FALSE	., NULL
JSP(JSTL)	., true		., false	., null
Velocity	., true		., false	., -
.+--------------------
	Translation of {{,true,}}, {{,false,}} and {{,null,}}


Translation a PL program which contains keyword {{,null,}} into Velocity script will cause error,
because Velocity doesn't have a keyword {{,null,}}.
But Kwartz will translate '{{,expr==null,}}' and '{{,expr!=null,}}' to '{{,!expr,}}' and '{{,expr,}}'
when translating into Velocity.


PL Program:
.-------------------- pl-boolean.plogic
:set(flag = obj == null? true : false)

:if (expr != null)
  :print("expr is not null.\n")
:else
  :print("epxr is null.\n")
:end
.--------------------

Output Script:
.____________________
.<<<:! ruby output.rb -a translate -l velocity guide.d/pl-boolean.plogic
.____________________



.$$ Variable	| pl-variable


A variable starts with alphabet or '{{,_,}}', and follows with alphabet or number or '{{,_,}}'.


You don't need to decrare variable, nor specify it's type{{(Because of this feature, it is very difficult to support "static language" in Kwartz.)}}.



.$$ Operator	| pl-op


There are several operators. Comparable operator is available for number and string{{(It is very difficult to support Perl in Kwartz, because Perl have different operator for number and String (like '==' and 'eq', '!=' and 'ne', ...).)}}.

.+--------------------
  Comparable operator	., {{,==  != < <= > >=,}}
  Logical operator      ., {{,&& || !,}}
  Arithmetic operator   ., {{,+ - * / %,}}
  String Concatenation operator  ., {{,.+,}}
  Conditional operator  ., {{,?:,}}
.+--------------------


Conditional Operator is available in Ruby, eRuby, ERB and PHP.
But it is not available in JSP (to be exact, in expression language of JSTL) and Velocity.
Therefore, conditional operator will be translated to if-statement in JSP or Velocity.

PL Program:
.-------------------- pl-condop.plogic
:set(color = ctr%2==0 ? '#CCCCFF' : '#FFCCCC')
.--------------------

Output Script:
.____________________
.<<<:! ruby output.rb -a translate guide.d/pl-condop.plogic
.____________________



.$$ Print | pl-print


{{,:print(...),}} is a print statement. Any expression can be in print statement.

PL Program:
.-------------------- pl-print.plogic
:print('foo', bar, "baz\n")   ## print a string and value of a variable
.--------------------

Output Script:
.____________________
.<<<:! ruby output.rb -a translate guide.d/pl-print.plogic
.____________________


When you make auto-sanitizing enabled, the output scripts of Ruby, PHP, eRuby and ERB will be the following:
.____________________
.<<<:! ruby output.rb -a translate -s -l ruby,php,eruby,erb guide.d/pl-print.plogic
.### PHP
.#foo<?php echo htmlspecialchars($bar); ?>baz
.#
.### eRuby
.#foo<%= CGI.escapeHTML(bar) %>baz
.#
.### ERB
.#foo<%= ERB::Util.h(bar) %>baz
.____________________


.#If conditional operator returns constant string or number, sanitizing will be off even when using auto-sanitizing.
.#
.#PL Program:
.#.-------------------- pl-print2.plogic
.### Sanitized.
.#:print("<option ", condition ? var1 : var2, ">\n")
.### Not sanitized.
.#:print("<option ", condition ? 'selected' : '', ">\n")
.#.--------------------
.#
.#Output Script:
.#.____________________
.#.<<<:! ruby output.rb -a translate -s -l ruby,php,eruby,erb guide.d/pl-print2.plogic
.#.____________________



.$$ Assignment | pl-set


'{{,:set({{/var/}}={{/value/}}),}}' is an assignment statement.
Spaces around '{{,(,}}' or '{{,=,}}' are allowed.


Also '{{,+=,}}', '{{,-=,}}', '{{,*=,}}', '{{,/=,}}', '{{,%=,}}' and '{{,.+=,}}' are allowed.
'{{,.+=,}}' means string concatination.


PL Program:
.-------------------- pl-set.plogic
:set(name = 'Foo')      ## assign a string 'Foo' into variable
:set(count += 1)        ## increment value of variable
:set(str .+= '.txt')    ## append a string
.--------------------

Output Script:
.____________________
.<<<:! ruby output.rb -a translate guide.d/pl-set.plogic
.____________________



.$$ Array and Hash	| pl-array


You can refer an array as {{,arr[expr],}}.
Also you can refer a hash in the same way.{{(Operators for array and hash are same, therefore it is difficult to support a language, say Perl, which use different operator for array and hash.)}}.


PL Program:
.-------------------- pl-array.plogic
:set(list[n] = 10)         ## assign into n-th element of array
:print(list[i], "\n")      ## print  i-th element of array
:set(hash['key'] = 'foo')  ## assign into a hash element
:print(hash['key'])        ## print a hash element
.--------------------

Output Script:
.____________________
.<<<:! ruby output.rb -a translate guide.d/pl-array.plogic
.____________________




You can also refer a hash as '{{,hash[:key],}}'.
'{{,key,}}' must be a string which is constructed only with alphabet, number or '{{,_,}}'.


'{{,hash[:key],}}' will be translated according to target programming language:
.+--------------------
   Target language	., Result of translation
.---------------------
   Ruby, eRuby, ERB	., {{,hash[:key],}}
   PHP			., {{,$hash['key'],}}
   JSP			., {{,hash['key'],}}
   Velocity		., {{,hash.key,}}
.+--------------------


PL Program:
.-------------------- pl-hash.plogic
:set(hash[:key] = 'foo')
:print(hash[:key])
.--------------------

Output Script:
.____________________
.<<<:! ruby output.rb -a translate guide.d/pl-hash.plogic
.____________________



.$$ Property	| pl-property


You can refer a property of an object as '{{,{{/object/}}.{{/property/}},}}'.
Property is not a method, so property cannot accept any arguments.


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


PL Program:
.-------------------- pl-property.plogic
:print(user.name)
.--------------------

Output Script:
.____________________
.<<<:! ruby output.rb -a translate guide.d/pl-property.plogic
.____________________



.$$ Iteration	| pl-foreach


{{,:foreach({{/variable/}}={{/value_list/}}) ... :end,}} represents iteration, known as foreach statement.
Each item in an array {{,{{/list/}},}} is assigned into variable {{,{{/var/}},}} in iteration.


PL Program:
.-------------------- pl-foreach.plogic
:foreach(item = list)
  :print(item, "\n")
:end
.--------------------

Output Script:
.____________________
.<<<:! ruby output.rb -a translate guide.d/pl-foreach.plogic
.____________________


You can also use while-statment.
Kwartz will cause an error if you translate while-statement into JSP or Velocity script,
because there is no JSTL custom tag or Velocity directive which are equvalent to while-statment.


PL Program:
.-------------------- pl-while.plogic
:set(i = 0)
:while(i < length)
  :print(list[i])
  :set(i += 1)
:end
.--------------------

Output Script:
.____________________
.<<<:! ruby output.rb -a translate -l ruby,php,eruby,erb guide.d/pl-while.plogic
.____________________


for-statement (like C or Java) is not available.



.$$ Conditional branch | pl-if


'{{,:if({{/condition/}}) ... :elsif({{/condition/}}) ... :else ... :end,}}' represents conditional branch.

PL Program:
.-------------------- pl-if.plogic
:if(ctr % 2 == 0)         ## if even
  :set(klass='even')      ## then assign a string 'even'
:else                     ## else
  :set(klass='odd')       ## assign a string 'odd'
:end
.--------------------

Output Script:
.____________________
.<<<:! ruby output.rb -a translate guide.d/pl-if.plogic
.____________________



.$$ Macro	| pl-macro


'{{,:macro({{/macro_name/}}) ... :end,}}' represents a macro definition.
'{{,:expand({{/macro_name/}}),}}' or '{{,@{{/macro_name/}},}}' represents a macro expantion.


The following is a sample of macro definition and expantion.
It represents start tag, content and end tag of an element '<li>#{item}#</li>'.


.-------------------- pl-macro.plogic
## macro definition
:macro(stag_item)
  :print("<li>")
:end

:macro(cont_item)
  :print(item)
:end

:macro(etag_item)
  :print("</li>")
:end

## macro expantion (it is equivalent to '<li>#{item}#</li>')
:expand(stag_item)
:expand(cont_item)
:expand(etag_item)
.--------------------


Macro expantion can be in macro definition.

.-------------------- pl-macro2.plogic
## macro definition
:macro(stag_item)
  :print("<li>")
:end

:macro(cont_item)
  :print(item)
:end

:macro(etag_item)
  :print("</li>")
:end

:macro(elem_item)    ## macro definition containing macro expantion
  :expand(stag_item)
  :expand(cont_item)
  :expand(etag_item)
:end

## equivalent to '<li>#{item}#</li>'
:expand(elem_item)
.--------------------

.#You can use {{,@{{/macro_name/}},}} as a short notation of macro expantion.
.#{{,@{{/macro_name/}},}} is equal to {{,:expand({{/macro_name/}},}}.


Special syntax for defining macro of an element is available.
The syntax is only for element macro definition.
.-------------------- pl-macro3.plogic
## Macro definition for an element
:elem(item)
  @stag
  @cont
  @etag
:end

## Above is equal to the following
:macro(elem_item)
  :expand(stag_item)
  :expand(cont_item)
  :expand(etag_item)
:end
.--------------------


You can use '{{,@stag,}}', '{{,@cont,}}' and '{{,@etag,}}' only in {{,:elem() .. :end,}}.
Using them in {{,:macro() .. :end,}} will be error.
.-------------------- pl-macro4.plogic
## NG
:macro(elem_item)	## must be ':elem(item)'
  @stag
  @cont
  @etag
:end
.--------------------


Kwartz provides a special syntax to define a macro of content of elements.
It is equivalent to a directive {{,id="value:{{/expr/}}",}}.
.--------------------
## replace content of element with epxression value
:value(item = expr)

## above is equal to the following
:macro(cont_item)
  :print(expr)
:end
.--------------------


Macro cannt accept any arguments.



.$$ Macro BEGIN and END		| pl-begend


'BEGIN' and 'END' are special macros.
If you define them, you can add codes at beginning/end of the output script.


Presentation data:
.-------------------- pl-begend.html
  Hello <span id="value:user">World</span>!
.--------------------


PL Program:
.-------------------- pl-begend.plogic
:macro(BEGIN)
  :print("<html>\n")
  :print(" <body>\n")
:end
:macro(END)
  :print(" </body>\n")
  :print("</html>\n")
:end
.--------------------


Output script:
.____________________
.<<<:! ruby output.rb -l ruby,php -p guide.d/pl-begend.plogic guide.d/pl-begend.html
.____________________




.$$ Function	| pl-func

You can use the following two functions in PL.
.: E({{/expr/}})
	Sanitize expression {{/expr/}}. Sanitizing is done even when command line option for sanitizing is not specified.
.: X({{/expr/}})
	Don't sanitize expression {{/expr/}}, even when command line options for sanitizing is specified.

Currently, you cannot define or use any function except above two.




.$$ Empty	| pl-empty

'{{,empty,}}' is a keyword in order to check whether value is null or empty string.
It can be praced only at the right-side of {{,==,}} or {{,!=,}} operator.

PL Program:
.-------------------- pl-empty.plogic
:if (str1 == empty)
  :print("str1 is empty.\n")
:elsif(str2 != empty)
  :print("str2 is not empty.\n")
:end
.--------------------

Output Script:
.____________________
.<<<:! ruby output.rb -a translate guide.d/pl-empty.plogic
.____________________



.$$ Load presentation logic file 		| pl-load


{{,:load('{{/filename/}}'),}} loads other presentation logic file.
You can specify directories at where files are placed by command line option {{,--load_path={{/dir1/}},{{/dir2/}},...,}}.


PL Program:
.-------------------- pl-load.plogic
:load('file.plogic')
.--------------------

{{,:load(),}} can load only presentation logic file.
It cannot load presentation data file or output program.




.$$ Raw-code | pl-rawcode


Code of the target program language (such as Ruby, PHP, ...) can be in PL program.
'{{,::: {{/raw code/}},}}' represents a raw-code of target program language.
Kwartz outputs a string after '{{,:::,}}' as a raw-code.


The following is an example which include PHP code.


PL Program:
.-------------------- pl-rawcode.plogic
::: <?php foreach($hash as $key => $value) { ?>
:print("key=", key, " value=", value, "\n")
::: <?php } ?>
.--------------------

Output Script:
.____________________
.<<<:! ruby output.rb -a translate -l php guide.d/pl-rawcode.plogic
.# <?php foreach($hash as $key => $value) { ?>
.#key=<?php echo $key; ?> value=<?php echo $value; ?>
.# <% } %>
.____________________


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

Command line option '--enable_eruby=true' enables you to embed several language code in presentation logic file.
See '{{<Enable eRuby code in presentation logic|#tips-eruby>}}' for more detail.




.#.$$ Variable scope	| pl-scope
.#
.#
.#There is no concept about 'Variable scope'.
.#For example, you cannot define a variable which is enabled only in a certain macro definition.
.#It means that if you define a variable, it is able to be referred from anywhere in template.
.#.#All variables are global.
.#.#A macro is not a function or a procedure, so 'local variables in a funtion/procedure' doesn't exist.
.#
.#
.#In the following example, macro 'cont_item' use a variable 'item' which is assigned in macro 'elem_item'.
.#
.#.-------------------- pl-scope.plogic
.#:macro(stag_item)
.#  :print("<li id=\"item\">")
.#:end
.#
.#:macro(cont_item)
.#  :print(item)                # use a variable 'item'
.#:end
.#
.#:macro(etag_item)
.#  :print("</li>")
.#:end
.#
.#:macro(elem_item)
.#  :foreach(item = item_list)  # assign value into a variable 'item'
.#    :expand(stag_item)
.#    :expand(cont_item)
.#    :expand(etag_item)
.#  :end
.#:end
.#
.#
.## ex. if item_list is 'foo', 'bar', ...
.##     then output is <li>foo</li><li>bar</li>...
.#:expand(elem_item)
.#.--------------------
.#



.$$ Global and Local Variable	 | pl-global-local


In Kwartz, variables are called Global variables which are setted in main program and passed to output script.
And variables are called Local variables which are used only in template.


Assum the following presentation data and presentation logic:


Presentation data (analyze.html) :
.-------------------- analyze.html
<html>
  <body>
    <table>
      <caption id="value:{{*title*}}">Sample</caption>
      <tr id="item_list" bgcolor="#{{{*color*}}}#">
        <td id="value:{{*item_ctr*}}">1</td>
	<td id="value:{{*item*}}">Foo</td>
      </tr>
    </table>
  </body>
</html>
.--------------------


Presentation logic (analyze.plogic) :
.-------------------- analyze.plogic
:elem(item_list)
  :set({{*item_ctr*}} = 0)
  :foreach({{*item*}} = {{*item_list*}})
    :set({{*item_ctr*}} += 1)
    :set({{*color*}} = {{*item_ctr*}}%2 == 0 ? '#FFCCCC' : '#CCCCFF')
    @stag
    @cont
    @etag
  :end
:end
.--------------------


There are several variables. They are classified as bellow:
.[ Global variables ]
	Variables {{,title,}} and {{,item_list,}} are needed to be setted in main program and passed to template.
	These variables are called Global variables in Kwartz.
.[ Local variables ]
	Variables {{,item,}}, {{,item_ctr,}} and {{,color,}} are used only in template.
	These variables are called Local variables in Kwartz.


Invoking kwartz command with command option {{,-a analyze,}} analyzes template and reports global/local variables.
.--------------------
$ kwartz -p analyze.plogic -a analyze analyze.html
global variables: {{*title*}} {{*item_list*}}
local variables:  {{*color*}} {{*item*}} {{*item_ctr*}}
.--------------------


Kwartz detemines global/lobal variables according to the following rule:
.* When Kwartz finds a new variable ...
    .- If it appears in left-side of assignment, Kwartz recognizes it as local variable.
    .- If it appears as loop variable of foreach statement, Kwartz recognizes it as local variable.
    .- Otherwize, Kwartz recognizes it as global variable.


Kwartz reports warnings if you global variables are appeared in left-side of assignment or used as loop variable of foreach statement.
Because role of template system is to display global variables, and templates should not change or modify values of global variables.
In addition, kwartz reports warning when uninitalized local variables are used in template.


Analyzing template and reporting global/local variables are very useful, especially presentation data/logic are large and complex.
It also helps you to find typo of variable names.




.$$ Notes	| pl-notes


.#.* String is represented only as {{,'...',}}.  {{,"...",}} causes an error.
.#	.--------------------
.#	:set(str = "foo")		## NG
.#	:set(str = 'foo')		## OK
.#	.--------------------


.* '{{,:print(condition?v1:v2),}}' or '{{,:set(var=flag?v1:v2),}}' will cause syntax error,
   because kwartz recognize '{{,:v2,}}' as beginning of statement (like '{{,:print,}}' or '{{,:if,}}').
   You should cover '{{,:v2,}}' with '{{,(),}}' or insert a space between '{{,:,}}' and '{{,v2,}}'.
	.--------------------
	:set(var=flag?v1:v2)            ## NG
	:set(var=flag?v1:(v2))          ## OK
	:set(var=flag?v1: v2)           ## OK
	.--------------------


.* Nested macro definition/expantion will be in infinite-loop when compiling.
   Please take care not to define nested macro.
	.--------------------
	:macro(elem_foo)
	  :expand(stag_foo)
	  :expand(elem_foo)		## nested macro
	  :expand(etag_foo)
	:end
	
	:expand(elem_foo)		## infinite-loop
	.--------------------



.$$ Features under consideration | pl-infuture

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

.* break, continue
.* user-define function/procedure
.* method call (with arguments)
.* macro with arguments
.* creating an array or hash



.$ Practical Examples	| practice




.$$ Border colored table                   | practice-table1
.#.$$ Border colored table with different background colors in odd/even lines | practice-table1

This is a example of border colored table.
Each colors in odd lines and even lines are different.
The example is so easy that you'll do it only with directives.
.#The same example is re-written to 
.#The example in the previous section is changed to use directives to describe presentation logic.

Presentation data(table1.html):
.-------------------- table1.html
<table border="0">
  <tbody {{*id="Foreach:user=user_list"*}}>
    <tr bgcolor="#CCCCFF"
        {{*id="attr:bgcolor=color;set:color=user_ctr%2==0?'#FFCCCC':'#CCCCFF'"*}}>
      <td {{*id="value:user[:name]"*}}>foo</td>
      <td {{*id="value:user[:email]"*}}>foo@foo.com</td>
    </tr>
    <tr {{*id="dummy:d1"*}}>
      <td>bar</td>
      <td>bar@bar.net</td>
    </tr>
    <tr {{*id="dummy:d2"*}}>
      <td>baz</td>
      <td>baz@baz.org</td>
    </tr>
  </tbody>
</table>
.--------------------

Intermediate code:
.____________________
.<<<:! kwartz -a convert guide.d/table1.html
.____________________

Compile:
.====================
$ kwartz -l ruby     table1.html > table1.rb
$ kwartz -l ruby2    table1.html > table1.rb2
$ kwartz -l php      table1.html > table1.php
$ kwartz -l jsp      table1.html > table1.jsp
$ kwartz -l eruby    table1.html > table1.rhtml
$ kwartz -l erb      table1.html > table1.erb
$ kwartz -l velocity table1.html > table1.vm
.====================


.#Output Program:
.#.____________________
.#.<<<:! ruby output.rb guide.d/table1.html
.#.____________________



The following output scripts will be created after compiling.

Ruby:
.____________________
.<<<:! kwartz -l ruby guide.d/table1.html
.____________________

Ruby2:
.____________________
.<<<:! kwartz -l ruby2 guide.d/table1.html
.____________________

PHP:
.____________________
.<<<:! kwartz -l php guide.d/table1.html
.____________________

JSP:
.____________________
.<<<:! kwartz -l jsp guide.d/table1.html
.____________________

eRuby:
.____________________
.<<<:! kwartz -l eruby guide.d/table1.html
.____________________

ERB:
.____________________
.<<<:! kwartz -l erb guide.d/table1.html
.____________________

Velocity:
.____________________
.<<<:! kwartz -l velocity guide.d/table1.html
.____________________




.#.$$ Border colored table with different background colors in odd/even line (2) | practice-table2
.#
.#
.#The previous example can be performed only with marking directive.
.#
.#
.#Here is a presentation data:
.#
.#
.#Presentation data(table2.html):
.#.-------------------- table2.html
.#<table border="0">
.#  <tbody {{*id="mark:user_list"*}}>
.#    <tr bgcolor="#CCCCFF" {{*id="mark:odd"*}}>
.#      <td {{*id="mark:user_name"*}}>foo</td>
.#      <td {{*id="mark:user_mail"*}}>foo@foo.com</td>
.#    </tr>
.#    <tr bgcolor="#FFCCCC" {{*id="mark:even"*}}>
.#      <td {{*id="mark:user_name"*}}>bar</td>
.#      <td {{*id="mark:user_mail"*}}>bar@foo.com</td>
.#    </tr>
.#    <tr {{*id="mark:dummy"*}}>
.#      <td>baz</td>
.#      <td>baz@baz.org</td>
.#    </tr>
.#  </tbody>
.#</table>
.#.--------------------
.#
.#
.#And the following is a presentation logic.
.#.* Element which is marked 'odd'({{,mark:odd,}})/'even'({{,mark:even,}}) represents odd/even line.
.#.* Expand macros of odd/even elements in iteration.
.#   And a dummy element ({{,mark:dummy,}}) is ignored.
.#.* 'User_name' element ({{,mark:user_name,}}) is overwritten to print value of {{,user[:name],}},
.#   and the same is 'user_mail' element.
.#.* Same marking is used in odd/even line data elements because they print same values.
.#
.#
.#Presentation logic (table2.plogic):
.#.-------------------- table2.plogic
.### do iteration
.#:elem(user_list)
.#  @stag
.#  :set(user_ctr = 0)
.#  :foreach(user = user_list)
.#    :set(user_ctr += 1)
.#    :if(user_ctr % 2 == 0)
.#      @elem_even             ## expand even line element
.#    :else
.#      @elem_odd              ## expand odd line element
.#    :end
.#  :end
.#  @etag
.#:end
.#
.### overwrite elements to print user[:name] and user[:mail]
.#:elem(user_name)
.#  @stag
.#  :print(user[:name])        ## print user[:name] instead of @cont
.#  @etag
.#:end
.#
.#:elem(user_mail)
.#  @stag
.#  :print(user[:mail])        ## print user[:mail] instead of @cont
.#  @etag
.#:end
.#.--------------------
.#
.#
.#Compile:
.#.====================
.#$ kwartz -p table2.plogic -l ruby     table2.html > table2.rb
.#$ kwartz -p table2.plogic -l php      table2.html > table2.php
.#$ kwartz -p table2.plogic -l jsp      table2.html > table2.jsp
.#$ kwartz -p table2.plogic -l eruby    table2.html > table2.rhtml
.#$ kwartz -p table2.plogic -l erb      table2.html > table2.erb
.#$ kwartz -p table2.plogic -l velocity table2.html > table2.vm
.#.====================
.#
.#
.#.#Output Program:
.#.#.____________________
.#.#.<<<:! ruby output.rb guide.d/table2.html
.#.#.____________________
.#
.#
.#The following output scripts will be created after compile.
.#
.#Ruby:
.#.____________________
.#.<<<:! kwartz -p guide.d/table2.plogic -l ruby guide.d/table2.html
.#.____________________
.#
.#PHP:
.#.____________________
.#.<<<:! kwartz -p guide.d/table2.plogic -l php guide.d/table2.html
.#.____________________
.#
.#JSP:
.#.____________________
.#.<<<:! kwartz -p guide.d/table2.plogic -l jsp guide.d/table2.html
.#.____________________
.#
.#eRuby:
.#.____________________
.#.<<<:! kwartz -p guide.d/table2.plogic -l eruby guide.d/table2.html
.#.____________________
.#
.#ERB:
.#.____________________
.#.<<<:! kwartz -p guide.d/table2.plogic -l erb guide.d/table2.html
.#.____________________
.#
.#Velocity:
.#.____________________
.#.<<<:! kwartz -p guide.d/table2.plogic -l velocity guide.d/table2.html
.#.____________________
.#
.#



.$$ Navigation of 'Next' or 'Previous'	| practice-navilink


If there is a sequence of HTML files, each files should have navigation link such as 'Next page' or 'Previous page'.
Here we create the next/previous link.
.* In main program, set the url of next/previous page to variable {{,next_url,}}/{{,prev_url,}}.
   If there is not next/previous page, set null to {{,next_url,}}/{{,prev_url,}}.
.* In template, print navigation link with <a></a> tag and variables {{,next_url,}}/{{,prev_url,}}.
   If variables are null, then don't print <a></a> tag.
.* Navigation apprears at the top and the end of document.


Presentation Data (navilink.html):
.-------------------- navilink.html
<html>
  <body>
    <span {{*id="mark:navilink"*}}>
      <a {{*id="mark:prev"*}} href="{{*#{prev_url}#*}}">
        &lt; Previous page
      </a>
      &nbsp;
      <a {{*id="mark:next"*}} href="{{*#{next_url}#*}}">
        Next page &gt;
      </a>
    </span>

    ......
    ......
    ......

    <span {{*id="mark:navilink2"*}}>
      &lt; Previous page  &nbsp;  Next page &gt;
    </span>

  </body>
</html>
.--------------------


Presentation Logic (navilink.plogic):
.-------------------- navilink.plogic
## if URL is null then don't print start-tag and end-tag
:elem(next)
  :if(next_url != null)
    @stag
    @cont
    @etag
  :else
    @cont
  :end
:end
:elem(prev)
  :if(prev_url != null)
    @stag
    @cont
    @etag
  :else
    @cont
  :end
:end

## replace an element 'navi2' with an element 'navi'.
:elem(navilink2)
  @elem_navilink
:end
.--------------------


You can use {{,kd="replace:navilink",}} to replace an element named 'navilink2' with an element named 'navilink'.



Compile:
.====================
$ kwartz -p navilink.plogic -l ruby  navilink.html > navilink.rb
$ kwartz -p navilink.plogic -l ruby2 navilink.html > navilink.rb2
$ kwartz -p navilink.plogic -l php   navilink.html > navilink.php
$ kwartz -p navilink.plogic -l jsp   navilink.html > navilink.jsp
$ kwartz -p navilink.plogic -l eruby navilink.html > navilink.rhtml
$ kwartz -p navilink.plogic -l erb   navilink.html > navilink.erb
$ kwartz -p navilink.plogic -l velocity navilink.html > navilink.vm
.====================


.#Output program:
.#.____________________
.#.<<<:! ruby output.rb -p guide.d/navilink.plogic guide.d/navilink.html
.#.____________________


The following output scripts will be created after compiling.

Ruby:
.____________________
.<<<:! ruby output.rb -l ruby --no_langheader -p guide.d/navilink.plogic guide.d/navilink.html
.____________________

Ruby2:
.____________________
.<<<:! ruby output.rb -l ruby2 --no_langheader -p guide.d/navilink.plogic guide.d/navilink.html
.____________________

PHP:
.____________________
.<<<:! ruby output.rb -l php --no_langheader -p guide.d/navilink.plogic guide.d/navilink.html
.____________________

JSP:
.____________________
.<<<:! kwartz -l jsp -p guide.d/navilink.plogic guide.d/navilink.html
.____________________

eRuby:
.____________________
.<<<:! ruby output.rb -l eruby --no_langheader -p guide.d/navilink.plogic guide.d/navilink.html
.____________________

ERB:
.____________________
.<<<:! ruby output.rb -l erb --no_langheader -p guide.d/navilink.plogic guide.d/navilink.html
.____________________

Velocity:
.____________________
.<<<:! ruby output.rb -l velocity --no_langheader -p guide.d/navilink.plogic guide.d/navilink.html
.____________________




.$$ Breadclumbs 	| practice-breadcrumbs

It is very popular that Web page have links such as 'Home > Ruby > Kwartz'.
It is called 'Breadcrumbs' or 'Trail'.


Here we create that.
.* In main program, set title and path to a hash, and add it to an array.
.* In template, print title and path, separating with '&gt;'.



.-------------------- breadcrumbs.main
## Ruby
breadcrumbs = []
breadcrumbs << { :title => 'Home',   :path => '/' }
breadcrumbs << { :title => 'Ruby',   :path => '/ruby/' }
breadcrumbs << { :title => 'Kwartz', :path => '/ruby/kwartz/' }

## PHP
$breadcrumbs = array('title' => 'Home',   'path' => '/');
$breadcrumbs = array('title' => 'Ruby',   'path' => '/ruby/');
$breadcrumbs = array('title' => 'Kwartz', 'path' => '/ruby/kwartz/');

## Java
List breadcrumbs = new ArrayList();
Map  hash = new HashMap();
hash.put('title', 'Home');
hash.put('path',  '/');
breadcrumbs.add(hash);
hash = new HashMap();
hash.put('title', 'Ruby')
hash.put('path', '/ruby/')
breadcrumbs.add(hash);
hash = new HashMap();
hash.put('title', 'Kwartz')
hash.put('path', '/ruby/kwartz/')
breadcrumbs.add(hash);
.--------------------


Presentation Data:
.-------------------- breadcrumbs.html
<span {{*id="mark:breadcrumbs"*}}>
  <a {{*id="mark:item"*}} href="{{*#{item_path}#*}}">
    <span {{*id="value:item_title"*}}>Home</span>
  </a>
  <span {{*id="mark:arrow"*}}> &gt; </span>
</span>
.--------------------


Presentation Logic:
.-------------------- breadcrumbs.plogic
:elem(breadcrumbs)
  :set(item_ctr = 0)
  :foreach(item = breadcrumbs)
    :set(item_ctr += 1)
    :if(item_ctr > 1)       ## each time  except first time
      @elem_arrow           ## print &lt;
    :end
    @elem_item              ## and print <a></a>.
  :end
:end

:elem(item)
  :set(item_path  = item[:path])   ## retrieve path and
  :set(item_title = item[:title])  ## title from a hash.
  :if(item_path!=null)
    @stag
    @cont
    @etag
  :else                     ## if path is null then
    @cont                   ## don't print <a></a>.
  :end
:end
.--------------------


Compile:
.====================
$ kwartz -p breadcrumbs.plogic -l ruby  breadcrumbs.html > breadcrumbs.rb
$ kwartz -p breadcrumbs.plogic -l ruby2 breadcrumbs.html > breadcrumbs.rb2
$ kwartz -p breadcrumbs.plogic -l php   breadcrumbs.html > breadcrumbs.php
$ kwartz -p breadcrumbs.plogic -l jsp   breadcrumbs.html > breadcrumbs.jsp
$ kwartz -p breadcrumbs.plogic -l eruby breadcrumbs.html > breadcrumbs.rhtml
$ kwartz -p breadcrumbs.plogic -l erb   breadcrumbs.html > breadcrumbs.erb
$ kwartz -p breadcrumbs.plogic -l velocity breadcrumbs.html > breadcrumbs.vm
.====================


.#Output program:
.#.____________________
.#.<<<:! ruby output.rb -p guide.d/breadcrumbs.plogic guide.d/breadcrumbs.html
.#.____________________


The following output scripts will be created after compiling.

Ruby:
.____________________
.<<<:! kwartz -l ruby -p guide.d/breadcrumbs.plogic guide.d/breadcrumbs.html
.____________________

Ruby2:
.____________________
.<<<:! kwartz -l ruby2 -p guide.d/breadcrumbs.plogic guide.d/breadcrumbs.html
.____________________

PHP:
.____________________
.<<<:! kwartz -l php -p guide.d/breadcrumbs.plogic guide.d/breadcrumbs.html
.____________________

JSP:
.____________________
.<<<:! kwartz -l jsp -p guide.d/breadcrumbs.plogic guide.d/breadcrumbs.html
.____________________

eRuby:
.____________________
.<<<:! kwartz -l eruby -p guide.d/breadcrumbs.plogic guide.d/breadcrumbs.html
.____________________

ERB:
.____________________
.<<<:! kwartz -l erb -p guide.d/breadcrumbs.plogic guide.d/breadcrumbs.html
.____________________

Velocity:
.____________________
.<<<:! kwartz -l velocity -p guide.d/breadcrumbs.plogic guide.d/breadcrumbs.html
.____________________






This example shows you how to switch messages according to condition.


Presentaion data:
.--------------------
  <span {{*id="noerror"*}}>No errors.</span>
  <font {{*id="error"*}} color="red">Error occurred!</font>
.--------------------


Presentaion logic:
.--------------------
:elem(error_report)
  @stag
  :if(error_report == null)
     @elem_noerror	## prints 'No errors.'
  :else
     @elem_error	## prints 'Error occurred!'
  :end
  @etag
:end
.--------------------


In the above presentation logic, elements({{,@elem_noerror,}} and {{,@elem_noerror,}}) are used instead of content of {{,error_report,}} element.
This way is very useful. Remember it.


If you have an array which contains several error messages, say:


Presentaion data:
.-------------------- error_list.html
<font {{*id="error_list"*}} color="red">
  <span {{*id="value:error"*}}>Name is required.</span><br>
</font>
.--------------------


Presentation logic:
.-------------------- error_list.plogic
:elem(error_list)
  :if(error_list != null)
    @stag
    :foreach(error = error_list)
      @cont
    :end
    @cont
  :end
:end
.--------------------


From the viewpoint of 'Separation of presentation from business logic',
it is not a good idea to set error message in main program,
because error messages should be included in presentation layer.
Role of presentation layer is to determine what message should be used according to error code.

The following way is one of the idea to share the responsibility of template and main program.
.* In main program, error messages are stored in a hash using error code as keys.
.* In template, error messages are displayed with conditional branch.
   You may display error messages which are prepared in main program, or display original messages.


Presentaion Data:
.--------------------
<font {{*id="if:errors!=null"*}} color="red">
  <!-- Display error messages that is prepared in main program. -->
  <span {{*id="if:errors['age']!=null"*}}>#{errors['age']}#<br><span>
  <span {{*id="if:errors['tel']!=null"*}}>#{errors['tel']}#<br><span>
  <!-- Display original error messages. -->
  <span {{*id="if:errors['name']!=null"*}}>Name is required.<br></span>
  <span {{*id="if:errors['mail']!=null"*}}>Mail address is required.<br></span>
</font>
.--------------------


You may create a error message catalog and load it from main program.
It is also one of the preferred approach.




.$$ HTML Form | practice-form1

An example in this section is a form to register user name and gender.

There are several files in this example.
.[ register.cgi ]
	CGI Main program (Ruby).
.[ register.html ]
	Template for registration page.
.[ register.rhtml ]
	Output script for registration page (eRuby).
.[ finish.html ]
	Template for finished page.
.[ finish.rhtml ]
	Output script for finished page (eRuby).


Form CGI program (main program) is created with the following approach:
.* if no parameter given, then print registration page.
.* if parameters are given...
   .- if given parameters are valid then regist them and print finish page.
   .- else print registration page again with error messages.


Auto-sanitizing and eruby is adopted in this example.


Template for registration page(register.html):
.-------------------- register.html
<html>
 <body>
  <form action="/cgi-bin/register.cgi" method="POST">

   <span {{*id="if:error_list==null"*}}>
    <font color="#FF0000" {{*id="foreach:error=error_list"*}}>
     <span {{*id="value:error"*}}>Name is empty.</span><br>
    </font>
   </span>

   <table border="0" cellspacing="1" cellpadding="5">

    <tr>
     <td>Name:</td>
     <td>
      <input type="text" name="name" size="20"
             {{*id="attr:value=param[:name]"*}}>
     </td>
    </tr>

    <tr>
     <td>Gender:</td>
     <td>
.#      <span {{*id="set:chk_m=param[:gender]=='M'?'checked':''"*}}/>
.#      <span {{*id="set:chk_w=param[:gender]=='W'?'checked':''"*}}/>
      <input type="radio" name="gender" value="M"
.#             {{*#{chk_m}#*}}>Man
             {{*#{X(param[:gender]=='M'?'checked':'')}#*}}>Man
.#      <input type="radio" name="gender" value="M" {{*#{chk_m}#*}}>Man
      &nbsp;
      <input type="radio" name="gender" value="W"
.#             {{*#{chk_w}#*}}>Woman
             {{*#{X(param[:gender]=='W'?'checked':'')}#*}}>Woman
.#      <input type="radio" name="gender" value="W" {{*#{chk_w}#*}}>Woman
     </td>
    </tr>

    <tr>
     <td colspan="2" align="right">
      <input type="submit" value=" Regist ">
      <input type="reset"  value="reset">
     </td>
    </tr>

   </table>
  </form>
 </body>
</html>
.--------------------


Output script for registration page(register.rhtml):
.____________________
.<<<:! kwartz -l eruby -s guide.d/register.html
.____________________


Template of a finished page(finish.html):
.-------------------- finish.html
<html>
 <body>
  Registration finished with the following data:<br>
  Name:
   <span {{*id="value:param[:name]"*}}>Foo</span><br>
  Gender:
   <span {{*id="if:param[:gender]=='M'"*}}>Man</span>
   <span {{*id="if:param[:gender]=='W'"*}}>Woman</span>
 </body>
</html>
.--------------------

Output script for finished page(finish.rhtml):
.____________________
.<<<:! kwartz -l eruby -s guide.d/finish.html
.____________________

CGI main program(register.cgi):
.-------------------- register.cgi
#!/usr/bin/ruby

## create a hash object from CGI object
require 'cgi'
cgi = CGI.new
param = {}
cgi.param.each do |key, value|
  param[key.intern] = value[0]
end
param.default = ''

## action for submit button
.#flag_error = false
error_list = nil
if !param.empty? then
  ## check input data
  error_list = []
  if param[:name] == '' then
    error_list << 'Name is empty.'
  end
  case param[:gender]
  when 'M', 'W'
    # OK
  else
    error_list << 'Gender is not selected.'
  end
  .#flag_error = true if !error_list.empty?

  ## if input parameter is valid then print finished page(finish.rhtml),
  ## else print the sampe page(register.rhtml)
  .#if !flag_error then
  if error_list.empty? then
    error_list = nil
    filename = 'finish.rhtml'
    ... data registration process ...
  else
    filename = 'register.rhtml'
  end

.#  ## sanitizing
.#  param.each_value do |value|
.#    value.gsub!(/&/, '&amp;')
.#    value.gsub!(/>/, '&gt;')
.#    value.gsub!(/</, '&lt;')
.#    value.gsub!(/"/, '&quot;')
.#    value.gsub!(/'/, '&#39\;')
.#  end
end

## print web page
require 'eruby'
ERuby::import(filename)
.--------------------



.$$ Calendar		| practice-calendar

This is an example to show calendar, and also an example which explains component-approach development.
Here is the {{<final output|calendar-main.html>}}.


Calendar requires a complex presentation logic.
Therefore, this is one of the best example which represents effectiveness of 'separation of presentation logic and presentation data'.


This example has two presentation data files and two presentation logic files.
And main program is writtein in PHP.
.: calendar.html, calendar.plogic
	Presentation data file and presentation logic file to display calendar of a month.
.: calendar-page.html, calendar-page.plogic
	Presentation data file and presentation logic file for whole web page.
.: calendar-page.php
	Main program.



Presentation Data (calendar.html) :
.-------------------- calendar.html
     <table cellpadding="2" summary="">
       <caption>
	 <i {{*id="value:month"*}}>Jan</i>&nbsp;<i {{*id="value:year"*}}>20XX</i>
       </caption>
       <thead>
	 <tr bgcolor="#CCCCCC">
	   <th><span class="holiday">S</span></th>
	   <th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th>
	 </tr>
       </thead>
       <tbody>
	 <tr {{*id="mark:week"*}}>
	   <td><span {{*id="mark:day"*}} class="holiday">&nbsp;</span></td>
	   <td {{*id="dummy:d1"*}}>&nbsp;</td>
	   <td {{*id="dummy:d2"*}}>1</td>
	   <td {{*id="dummy:d3"*}}>2</td>
	   <td {{*id="dummy:d4"*}}>3</td>
	   <td {{*id="dummy:d5"*}}>4</td>
	   <td {{*id="dummy:d6"*}}>5</td>
	 </tr>
	 <tr {{*id="dummy:w1"*}}>
	   <td><span class="holiday">6</span></td>
	   <td>7</td><td>8</td><td>9</td>
	   <td>10</td><td>11</td><td>12</td>
	 </tr>
	 <tr {{*id="dummy:w2"*}}>
	   <td><span class="holiday">13</span></td>
	   <td>14</td><td>15</td><td>16</td>
	   <td>17</td><td>18</td><td>19</td>
	 </tr>
	 <tr {{*id="dummy:w3"*}}>
	   <td><span class="holiday">20</span></td>
	   <td>21</td><td>22</td><td>23</td>
	   <td>24</td><td>25</td><td>26</td>
	 </tr>
	 <tr {{*id="dummy:w4"*}}>
	   <td><span class="holiday">27</span></td>
	   <td>28</td><td>29</td><td>30</td>
	   <td>31</td><td>&nbsp;</td><td>&nbsp;</td>
	 </tr>
       </tbody>
     </table>
     &nbsp;
.--------------------


Presentation logic (calendar.plogic) :
.-------------------- calendar.plogic
:elem(week)

  :set(day = '&nbsp')
  :set(wday = 1)
  :while(wday < first_weekday)
    :if(wday == 1)
      @stag
    :end
    @cont
    :set(wday += 1)
  :end

  :set(day = 0)
  :set(wday -= 1)
  :while(day < num_days)
    :set(day += 1)
    :set(wday = wday % 7 + 1)
    :if(wday == 1)
      @stag
    :end
    @cont
    :if(wday == 7)
      @etag
    :end
  :end

  :if(wday != 7)
    :set(day = '&nbsp;')
    :while(wday != 6)
      @cont
      :set(wday += 1)
    :end
    @etag
  :end

:end

:elem(day)
  :if(wday == 1)
    @stag
    :print(day)
    @etag
  :else
    :print(day)
  :end
:end
.--------------------


Presentation data (calendar-page.html) :
.-------------------- calendar-page.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <style type="text/css">
      <!--
	.holiday   {color:#FF0000;}
	-->
    </style>
  </head>
  <body>
    
    <table border="0" summary="">
      <tr {{*id="mark:calendar_list"*}}>
	<td {{*id="mark:calendar"*}} valign="top">
	  .... calendar here ...
	</td>
      </tr>
    </table>
    
  </body>
</html>
.--------------------


Presentation logic (calendar-page.plogic) :
.-------------------- calendar-page.plogic
:elem(calendar_list)
  :set(calendar_ctr = 0)
  :foreach(calendar = calendar_list)
    :set(calendar_ctr += 1)
    :if(calendar_ctr % colnum == 1)
      @stag
    :end
    @cont
    :if(calendar_ctr % colnum == 0)
      @etag
    :end
  :end
  :if(calendar_ctr % colnum != 0)
    :set(calendar = '')
    :while(calendar_ctr % colnum != 0)
      @cont
      :set(calendar_ctr += 1)
    :end
    @etag
  :end
:end

:elem(calendar)
   @stag
   :print(calendar)
   @etag
:end
.--------------------



Main program (calendar-main.php) :
.-------------------- calendar-main.php
<?php
	// year, month, number of days, 1st weekday
	// (or use date() function)
	$month_data[] = array(2004, 'Jan', 31, 'Thu');
	$month_data[] = array(2004, 'Feb', 29, 'Sat');
	$month_data[] = array(2004, 'Mar', 31, 'Tue');
	$month_data[] = array(2004, 'Apr', 30, 'Thu');
	$month_data[] = array(2004, 'May', 31, 'Sat');
	$month_data[] = array(2004, 'Jun', 30, 'Tue');
	#$month_data[] = array(2004, 'Jul', 31, 'Thu');
	#$month_data[] = array(2004, 'Aug', 31, 'Sun');
	#$month_data[] = array(2004, 'Sep', 30, 'Wed');
	#$month_data[] = array(2004, 'Oct', 31, 'Fri');
	#$month_data[] = array(2004, 'Nov', 30, 'Mon');
	#$month_data[] = array(2004, 'Dec', 31, 'Wed');

	$weekday2num = array( 'Sun'=>1, 'Mon'=>2, 'Tue'=>3, 'Wed'=>4,
			      'Thu'=>5, 'Fri'=>6, 'Sat'=>7,);


	// output buffering start
	ob_start();

	// main loop
	$colnum = 4;
	foreach($month_data as $data) {
		$year	       = $data[0];
		$month         = $data[1];
		$num_days      = $data[2];
		$first_weekday = $weekday2num[$data[3]];

		// include 'calendar.inc' content as string
		include('calendar.php');
		$str = ob_get_contents();
		ob_clean();

		// append content string into $calendar_list[]
		$calendar_list[]  = $str;
	}

	// output buffering stop
	ob_end_clean();

	// include main page, with $calendar_list[]
	include('calendar-page.php');
 ?>
.--------------------


Compile and Execution :
.====================
$ kwartz -l php -p calendar.plogic calendar.html > calendar.php
$ kwartz -l php -p calendar-page.plogic calendar-page.html > calendar-page.php
$ php -q calendar-main.php > calendar-main.html
.====================



.$ Tips		| tips


.$$ Get output as string		| tips-outstring


It is possible to get result of executing output scrit as string in Ruby or PHP.


Use ruby2 or ERB in Ruby:
.--------------------
## ruby2
s = File.open('file.erb') { |f| f.read() }   # or File.read('file.erb') in 1.8
s.untaint
_s = ''
eval s
str = _s			  # get output as string

## ERB
s = File.open('file.erb') { |f| f.read() }   # or File.read('file.erb') in 1.8
require 'erb'
s.untaint
erb = ERB.new(s, $SAFE, '%')
str = erb.result(binding())       # get output as string
.--------------------


Use php2 or Output Buffering functions (ob_start(), ob_get_contents(), ob_end_clean()) in PHP:
.--------------------
// php2
<?php
	include('file.php');
	$str = $_s;
?>

// use output buffering functions
<?php
	ob_start();                 // start output buffering
	include('file.php');
	$str = ob_get_contents();   // get result as string
	ob_end_clean();             // stop output buffering
?>
.--------------------




.$$ Auto-compile with comaring timestamp		| tips-autocompile


Auto-compile is available.
Auto-compile is a function to compare each file's timestamp and compile it if needed.
Compilation will be done when:
.* Output script file does not exist.
.* Presentation  data file is newer than output script file.
.* Presentation logic file exists and it is newer than output script file.


Sorry, kwartz is implemented only in Ruby, so auto-compile function is available only for Ruby programmer.


You can use auto-compile with {{,Kwartz::compile(),}}.
Here is a sample of main program:
.--------------------
pdata  = 'sample.html'		# presentation data file
script = 'sample.rhtml'		# output script file
plogic = 'sample.plogic'	# presentation logic file
lang   = 'eruby'		# target language

{{*require 'kwartz'*}}
{{*Kwartz::compile(pdata, script, plogic, lang)*}}

requre 'eruby'
ERuby::import(script)
.--------------------



.$$ checked, selected, disabled	| tips-checked


A function to output 'checked="checked"', 'selected="selected"' or 'disabled="disabled"' easily
for HTML/XHTML is added in Kwartz.


.% {{,#{@CHECK({{/condition/}})}#,}} or {{,#{@C({{/condition/}})}#,}}
	Prints '{{,checked="checked",}}' if {{,{{/condition/}},}} is true
.% {{,#{@SELECT({{/condition/}})}#,}} or {{,#{@S({{/condition/}})}#,}}
	Prints '{{,selected="selected",}}' if {{,{{/condition/}},}} is true
.% {{,#{@DISABLE({{/condition/}})}#,}} or {{,#{@D({{/condition/}})}#,}}
	Prints '{{,disabled="disabled",}}' if {{,{{/condition/}},}} is true


For example, see the following presentation data:
.-------------------- 
<input type="radio" name="gender" value="M"
       {{*#{gender=='M' ? 'checked="checked"' : ''}#*}}>Man
<option name="lang" value="ruby"
       {{*#{lang=='ruby' ? 'selected="selected"' : ''}#*}}>Ruby
<input type="radio" name="os" value="win"
       {{*#{os=='mac' ? 'disabled="disabled"' : ''}#*}}>Windows
.--------------------


You can write the above presentation data more simply like this:
.-------------------- tips-checked.html
<input type="radio" name="gender" value="M"
       {{*#{@C(gender=='M')}#*}}>Man
<option name="lang" value="ruby"
       {{*#{@S(lang=='ruby')}#*}}>Ruby
<input type="radio" name="os" value="win"
       {{*#{@D(os=='mac')}#*}}>Windows
.--------------------


Kwartz will convert it into the following intermediate code:
.____________________
.<<<:! kwartz -a convert guide.d/tips-checked.html
.____________________


Note: The function is experimental. It may be changed or deleted in the future.




.$$ Enable eRuby code in presentation logic		| tips-eruby

Command line option {{,--enable_eruby=true,}} enables eRuby code appeared in presentation logic.
'%' notation is available and you can refer target language name by variable '__lang__' in eRuby code.


Presentation logic:
.-------------------- tips-eruby.plogic
:set(message = 'a sample message')
:set(number  = 20)
% if __lang__ == 'php'
::: <?php $str = sprintf('(%03d) %s', $number, $message); ?>
% elsif __lang__ == 'ruby'
::: s = '(%03d) %s' % [number, message]
% elsif __lang__ == 'erb'
:::% str = '(%03d) %s' % [number, message]
% elsif __lang__ == 'eruby'
::: <<% %>% str = '(%03d) %s' % [number, message] %<% %>>
% else
:set(s = '(' .+ number .+ ') ' .+ message)
% end
:print(s, "\n")
.--------------------


Output script:
.--------------------
.<<<:! ruby output.rb -a translate --enable_eruby=true guide.d/tips-eruby.plogic
.--------------------


eRuby code is executed with ERB.
If you are using Ruby 1.8.X or later, you don't need to install ERB because it is bundled with Ruby 1.8.X.
If you are using Ruby 1.6.X, you have to install ERB.





.$$ Environment variable KWARTZ_OPTIONS		| tips-envvar


You can specify kwartz command line options at an environment variable 'KWARTZ_OPTIONS'.


For example, if you are using ERB as a default target language and auto-sanitizing,
set the environment variable like this:
.====================
$ export KWARTZ_OPTIONS='-l erb -s'    # sh, bash
$ setenv KWARTZ_OPTIONS '-l erb -s'    # csh, tcsh
.====================


Value of the environment variable is overwrited by actual command-line options.
For example, when you have done the above setting and specified a command-line option '-l eruby',
kwartz will output a script for eRuby, not ERB.


Note: kwartz command parses a value of the environment variable by String#split(' ').
Therefore, kwartz command cannot parse a complex variable of the enviroment variable correctly.




.$$ Compile template as method of Ruby/PHP		| tips-mkmethod


Using 'mkmethod' script, you can compile template and define it as method or module of Ruby.

Usage of mkmethod is here:
.====================
bash$ mkmethod -h
Usage: mkmethod [-svh] [-p file] [-l lang] [-M module] [-m method] file.html
  -p file            : presentation logic file
  -l lang            : ruby/ruby2/eruby/erb/php/php2 (default 'ruby2')
  -M module/class    : module/class name (default none)
  -m method          : method name (default 'expand_' + file)
  -A arg1,arg2,...   : method arguments (default nil)
  -s                 : sanitizing (equals to '--escape=true')
  -h, --help         : print help and exit
  -v                 : print version and exit
  --optname=value    : options for kwartz
.====================


Command line option '-l ruby', '-l eruby' or '-l php' creates a method which prints result to standard output, '-l ruby2', '-l erb' or '-l php2' creates a method which returns output as a string. Default is 'ruby2'.

.====================
bash$ mkmethod -p hoge.plogic hoge.html
  def expand_hoge(_args)
    user = _args[:user]
    list = _args[:list]
    _s = ''
    _s << "Hello " << (user).to_s << "!\n"
    _s << "<ul>\n"
    for item in list do
      _s << "  <li>" << (item).to_s << "</li>\n"
    end
    _s << "</ul>\n"
    return _s
  end

bash$ mkmethod -l php2 -p hoge.plogic hoge.html
<?php
        function expand_hoge(&$_args) {
                $user = &$_args['user'];
                $list = &$_args['list'];
                ob_start();
?>
Hello <?php echo $user; ?>!
<ul>
<?php foreach ($list as $item) { ?>
  <li><?php echo $item; ?></li>
<?php } ?>
</ul>
<?php
                $_s = ob_get_contents();
                ob_end_clean();
                return $_s;
        } // function end
?>
.====================

Command line option '-M' enables you to specify module name in Ruby or class name in PHP.

.====================
bash$ mkmethod -p hoge.plogic -M Hoge hoge.html
module Hoge
  def self.expand_hoge(_args)
    user = _args[:user]
    list = _args[:list]
    _s = ''
    _s << "Hello " << (user).to_s << "!\n"
    _s << "<ul>\n"
    for item in list do
      _s << "  <li>" << (item).to_s << "</li>\n"
    end
    _s << "</ul>\n"
    return _s
  end
end

bash$ mkmethod -l php2 -p hoge.plogic -M Hoge hoge.html
<?php
class Hoge {
        function expand_hoge(&$_args) {
                $user = &$_args['user'];
                $list = &$_args['list'];
                ob_start();
?>
Hello <?php echo $user; ?>!
<ul>
<?php foreach ($list as $item) { ?>
  <li><?php echo $item; ?></li>
<?php } ?>
</ul>
<?php
                $_s = ob_get_contents();
                ob_end_clean();
                return $_s;
        } // function end
} // class end
?>
.====================


Script 'mkmethod' detects global variables of template automatically using Analyze function of Kwartz.
You can specify method arguments with command line option '-A'.

.====================
bash$ mkmethod -p hoge.plogic -M Hoge -A 'user,list' hoge.html
module Hoge
  def self.expand_hoge(_args)
    user = _args[:user]
    list = _args[:list]
    return self._expand_hoge(user, list)
  end
  def self._expand_hoge(user, list)
    _s = ''
    _s << "Hello " << (user).to_s << "!\n"
    _s << "<ul>\n"
    for item in list do
      _s << "  <li>" << (item).to_s << "</li>\n"
    end
    _s << "</ul>\n"
    return _s
  end
end

bash$ mkmethod -l php2 -p hoge.plogic -M Hoge -A 'user,list' hoge.html
<?php
class Hoge {
        function expand_hoge(&$_args) {
                $user = &$_args['user'];
                $list = &$_args['list'];
                return Hoge::_expand_hoge($user, $list);
        } // function end
        function _expand_hoge(&$user, &$list) {
                ob_start();
?>
Hello <?php echo $user; ?>!
<ul>
<?php foreach ($list as $item) { ?>
  <li><?php echo $item; ?></li>
<?php } ?>
</ul>
<?php
                $_s = ob_get_contents();
                ob_end_clean();
                return $_s;
        } // function end
} // class end
?>
.====================


Command line option for sanitizing '-s' or '--escape=true' are also avairable.




.$$ Use W3C Markup Validation Service		| tips-validator

{{<W3C|http://www.w3.org>}} provides Markup Validation service ({{<http://validator.w3.org>}}).
You will get errors when you tried it with Kwartz HTML template (presentation data file) because of 'kd' attribute.


There are nice PHP/CGI scripts (validator.php and validator.cgi) in Kwartz archive.
They delete 'kd' attribtes from a HTML file and pass it to W3C Markup Validation Service.
Put them at your web server and try it.
Or you can try it at {{<Kwartz website|http://www.kuwata-lab.com/webtech/kwartz/validator.php>}}.




.$$ Avoid same variable name as keywords | tips-keywords


If you are using Ruby or JSP, that is, languages which doesn't require '$' or other prefix for variable,
avoid same variable name as keywords of the language.
And also avoid the same name as built-in variables or build-in functions.


If you use a same name as keywords or build-in variables, you'll get strange errors.


For example, the following are {{<keywords in Ruby|http://www.ruby-lang.org/ja/man-1.6/index.cgi?cmd=view;name=%BB%FA%B6%E7%B9%BD%C2%A4#a.cd.bd.cc.f3.b8.ec>}}.

.____________________
    BEGIN    class    ensure   nil      self     when
    END      def      false    not      super    while
    alias    defined? for      or       then     yield
    and      do       if       redo     true
    begin    else     in       rescue   undef
    break    elsif    module   retry    unless
    case     end      next     return   until
.____________________
	Keywords in Ruby




JSP(and JSTL's Expression Lanugage) have the following built-in variables or keywords
 (see {{<JavaServer Pages(TM) Standard Tag Library Specification (Final Release)|http://jcp.org/aboutJava/communityprocess/final/jsr052/>}} for detail).

.____________________
    and		or	not
    eq		ne	lt	le	gt	ge
    div		mod
    true	false		null
    empty
    page	pageScope	request		requestScope
    session	sessionScope	application	applicationScope
    header	headerValues	param		paramValues
    cookie
.____________________
	keywords and built-in variables in JSP and JSTL Expression Language


PHP user doesn't need to wonder such problem because PHP needs to use variable prefix '$', but if you may change programming language from PHP to Java or other, you should remind this problem.



.$$ Use name 'param' as a variable for HTTP request parameters	| tips-param


URL Parameter variable is named '{{,param,}}' in JSTL's Expression Language.
You should also use name '{{,param,}}' for parameters in Ruby or PHP for portability of presentation layer.


For example, the following HTML page exists:
.--------------------
<form action="/cgi/form.cgi" method="post">
  User name: <input type="text" name="user"><br>
  Age:       <input type="text" name="age"><br>
  <input type="submit">
</form>
.--------------------


You should create the following presentation data.
.--------------------
Confirmation:
 User name:<span id="value:param['user']">Foobar</span><br>
 Age:      <span id="value:param['age']">99</span><br>
.--------------------


If you need portability of presentation data and logic, you should use name '{{,param,}}' as form parameters variable in all languages.


For example, in Ruby:
.--------------------
require 'cgi'
cgi = CGI.new
param = {}
cgi.params.each do |key,value|
  param[key] = value.first
end
....
s = File.open('form.rb') { |f| f.read }
s.untaint
eval s
## or ERuby::import('form.rhtml'), etc..
.--------------------


For example, in PHP:
.--------------------
<?php
     $param = &$_REQUEST;
     ....
     include('form.php');
 ?>
.--------------------

By the same reason, you should use '{{,cookie,}}' as cookie variable, and use '{{,session,}}' as session variable.


However, JSP doesn't allow us to change request values of parameters 
{{(It is because that there is getParameter() method in HttpServletRequest but not setParameter() method.)}}.
For example, you can write a code such as {{,$_POST['user'] = trim($_POST['user']);,}} in PHP,
but you cannot in JSP.
If you want avoid this restriction, you should set request parameters in a HashMap object and name it other name but '{{,param,}}'.


.--------------------
// Servlet Example
public void doPost(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {
   
   // Get HTTP request parameters and set them into HashMap object.
   String[] names = { 'name', 'age' };
   for (int i = 0; i < names.length; i++) {
      String key   = names[i];
      String value = (String)request.getParameter(key);
      if (value != null) {
         value = value.trim();            // trim an extra space
         params.put(key, value); 
      }
   }
   
   // Regist HashMap object with a name 'params'.
   // Use 'params' instead of 'param' in JSP and JSTL.
   request.setAttribute("params", params);
   
   // Forward to JSP
   String filename = "form.jsp";
   String url = filename;
   request.getRequestDispatcher(url).forward(request, response);
}
.--------------------



.$$ Allow only logical expression as conditional expresion	| tips-logical


It is very different in each programming language how to interpret conditional expression of if-statement or conditional operator.
Therefore, you should allow only logical expression in conditional expression.


For example, see the following presentation data:

.--------------------
<font id="if:error" color="red">
  ERROR! : #{error}#
</font>
.--------------------


In this case, programming languages takes each own ointerpretation of value of {{,error,}} as conditional expression.


.+--------------------
value of {{,error,}}	., Ruby		., PHP		., JSP(JSTL)	., Velocity
.--------------------
empty string ('')	., True		., False	., False	., True
string (not empty)	., True		., True		., False	., True
zero			., True		., False	., False	., True
number (not zero)	., True		., True		., False	., True
true			., True		., True		., True		., True
false			., False	., False	., False	., False
null			., False	., False	., False	., False
.+--------------------
	Results of interpretation of each programming languages


If you want to make templates portable, you should describe only logical expressin in conditional expression.
For example, '{{,:if(error),}}' should be '{{,:if(error!=null),}}' or '{{,:if(error!=''),}}',
and '{{,:if(!error),}}' should be '{{,:if(error==null),}}' or '{{,:if(error==''),}}'.


If you want to check if string is null or empty, use keyword 'empty'.
See {{<empty|#pl-empty>}} for detail about keyword 'empty'.



.$ Appendix		| appendix*

.$$ Appendix1: kwartz command | appendix-command*

Script 'kwartz' is a commad-line script to convert, translate and compile a HTML template into outptu script.

You remember these terms? OK, I'll show you again.

.[ Convert ]
	Transform presentation data into intermediate code.

.[ Translate ]
	Merge intermediate code and presentation logic, and transform them into output script.

.[ Compile ]
	Transform presentation data and presentation logic into output script.
	'Compile' means 'convert and traslate'.


And here is the usage of 'kwartz' script.


Usage:
.% {{,kwartz [options...] [-p {{/plogic-file/}}] file.html > file.output,}}
	Process one file (normal mode).

.% {{,kwartz -O {{/outfile-suffix/}} [-P {{/plogic-suffix/}}] [options...] *.html,}}
	Process each files (batch mode).
	You must specify suffix of output script file with option -O.
	And you may specify suffix of presentation logic file with option -P.


Options:
.[-h, --help]
	Help.

.[-v]
	Version information.

.[-a {{/action/}}]
	Action to do. {{/action/}} may be 'convert', 'translate', 'compile'(default) or 'analyze'.

.[-l {{/lang/}}]
	Target language of output script. {{/lang/}} may be
	ruby, ruby2, php, php2, jsp, eruby, erb, erbscan, velocity.

.[-s]
	Make auto-sanitizing enabled. All language but velocity can be sanitized.
	This option is equal to {{,--escape=true,}}.

.[-p {{/plogic-file/}}]
	Filename of presentation logic. It is possible to specify several filename using '{{,,,}}' as a separator.

.[-O {{/outfile-suffix/}}]
	Suffix of output file. Kwartz will be 'batch mode' when option -O is specified.

.[-P {{/plogic-suffix/}}]
	Suffix of presentation logic file. Used with batch-mode.

.[-T]
	Compare timestamp. If output script file is newer than input, kwartz will do nothing.
	Used with batch-mode.

.[-S]
	Suppress messages. Used with batch-mode.

.[--attr_name={{/name/}}]
	Attribute name used as a directive. Default is 'kd'.

.[--charset={{/charset/}}]
	Character set. kwartz will print '{{,<%@ page contentType="text/html; charset={{/charset/}}" %>,}}' in JSP.

.[--delete_idattr={{/true/}}|{{/false/}}]
	Delete {{,id="name",}} from presentation data.

.[--enable_eruby={{/true/}}|{{/false/}}]
	Use eRuby as a preprocessor for presentation logic. '%' notation is available.
	Variable '{{,__lang__,}}' represents target language name. It needs ERB to be installed.

.[--escape={{/true/}}|{{/false/}}]
	Auto-sanitizing.

.[--even_value={{/value/}}]
	Even value. Default is {{,'even',}}. Directive FOREACH and LIST will use this value.

.[--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='',}}.

.[--include_path={{/dir1/}},{{/dir2/}}],...
	Specify directories from which '{{,include,}}' directive includes.

.[--load_path={{/dir1/}},{{/dir2/}}],...
	Specify directories from which '{{,load,}}' directive or {{,:load(),}} statement loads.

.[--odd_value={{/value/}}]
	Odd value. Default is {{,'odd',}}. Directive FOREACH and LIST will use this value.





Example:

.#.: file1.html ==> file1.rb
.*	Compile presentation data file 'file1.html' and get an output script 'file1.rb'.
	The target language is Ruby.
	.====================
	$ kwartz -l ruby file1.html > file1.rb
	or
	$ kwartz -l ruby -O .rb file1.html
	.====================
	

.#.: file1.html + file1.plogic ==> file1.php
.*	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
	or
	$ kwartz -l php -p file1.plogic -O .php file1.html
	or
	$ kwartz -l php -O .php -P .plogic file1.html
	.====================
	

.#.: *.html + *.plogic ==> *.jsp
.*	Batch mode; Compile each presentation data file and presentaion logic file into output script(*.jsp) with charset EUC-JP.
	The target language is JSP.
	.====================
	$ kwartz -l jsp -O .jsp -P .plogic --charset=EUC-JP *.html
	.====================
	

.#.: *.html ==> intermediate code
.*	Convert presentation data into intermediate code.
	.====================
	$ kwartz -a convert file1.html | more
	.====================
	



.$$ appendix2: BNF of PL(Presentation Language)	| appendix-bnf*

(undocumented)


.#@EOF


.-------------------- calendar.sh
#!/bin/sh -x
kwartz -l php -p calendar.plogic calendar.html > calendar.php
kwartz -l php -p calendar-page.plogic calendar-page.html > calendar-page.php
php -q calendar-main.php > calendar-main.html
.--------------------
