Kwartz-Ruby Users' Guide

release: $Release$

1   Introduction to Kwartz

1-1   What's Kwartz?

Kwartz(*2) is a template system which realized the concept of 'Independence of Presentation Logic'(IoPL). It means that Kwartz separates presentaion logics from both presentation data (typically HTML document) and business logics.

You know CSS (Cascading Style Sheet). CSS separates design from HTML file. In the same way, Kwartz separates presentation logics from HTML template. If you are familiar with CSS, you'll be also familiar with Kwartz.

The following figure show the relation of HTML, CSS, JavaScript, and Kwartz.

  • HTML represents document structure.
  • CSS represents document design.
  • JavaScript represents client-side logics.
  • Kwartz represents server-side presentation logics.
    (Notice that Kwartz represents only presentation logics and not business logics.)
Figure1. Components in Presentation Layer.
relation of HTML, CSS, JavaScript, and Kwartz

If you are interested in concept of Kwartz, see this presentation.

(*2)
'Kwartz' is pronounced like 'Quartz'.

1-2   Features Overview

Kwartz has the following features:

Separates presentation logic from presentation data.

Using template systems such as Smarty, Velocity, XMLC, amrita, etc, you can separate HTML design 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 need not mix presentation logic into HTML files nor main program.

Very fast

Kwartz creates a script from a template (= presentation data and presentaion logic). All you have to do in main program is to call the output script. Because Kwartz doesn't use DOM trees or the like, it is both fast and light-weight.

Multi-languages support

Kwartz can create output scripts for Ruby(eRuby), PHP, JSP(JSTL 1.2 & 1.1). Presentation logics are written in each language(*3). This approach gives you the power of the target language fully. For example, you can write Ruby on Rails helper methods (such as link_to, form_tag, and so on) directly as a part of presentation logic.

Doesn't break HTML design at all

You must use directives like {foreach ...}{/foreach} in Smarty or #foreach(...) in Jakarta Velocity. These directives break the HTML design of template. Kwartz doesn't break HTML design because Kwartz uses id or kw:d attributes for marking in an HTML template.

Able to handle any text file

Kwartz uses an original template parser; not using an HTML or XML parser, it is able to handle any type of text file (HTML, PostScript, CSV, and so on). This also means that Kwartz can handle non-well-formed XML files, as well as well-formed XML files. This is an advantage of Kwartz against Enhydra XMLC or amrita, which handle only XML/HTML files.

Auto-escape and Partial-escape

Kwartz can do sanitizing automatically. You don't need to write 'CGI.escapeHTML(var)' or 'htmlspecialchars($var)'. You are free to turn sanitizing on/off, as well specifying which parts of the template to sanitize.

(*3)
Previous version of Kwartz adopt original language and convert it to each target language(Ruby, PHP, JSTL, and so on). From version 3.0, it is required to write presentation logic in target language.

1-3   Quick Example

Here is an example of presentation data file (= HTML template).

example1.html
<table>
  <tr id="mark:list1">
    <td id="mark:item1">foo</td>
  </tr>
</table>

Points:

  • Mark elements by id="mark:xxx" or id="xxx". The former will be remove at compile stage but the latter will be remained.
  • No presentation logics in HTML file.

Here is an example of presentation logic file.

example1.plogic
/* The element which is marked by 'id="mark:list1"' */
#list1 {
  logic: {
    for member in @members
      _stag           # start tag
      _cont           # content
      _etag           # end tag
    end
  }
}

/* The element which is marked by 'id="mark:item1"' */
#item1 {
  /* replace the content with value of a variable 'member' */
  value: member;
}

Points:

  • Presentation logic is separated from HTML file.
  • Format is very similar to CSS with which you are familiar.
  • Don't forget the semicolon at the end of line!

You must compile presentation data and logic files.

Compile
$ kwartz -l ruby -p example1.plogic example1.html > example1.rhtml
Generated script (example1.rhtml)
<table>
<%     for member in @members %>
  <tr>
    <td><%= member %></td>
  </tr>
<%     end %>
</table>

Points:

  • Kwartz compile presentation data and logic files into eRuby, PHP, JSP, Velocity, ....
  • This is why Kwartz is so fast and can support multiple programming languages.

1-4   Complex Example

Next is bordered table example which is a little complex than previous.

Presentation Data (example2.html):
<table>
 <tr bgcolor="#CCCCFF" id="mark:list">
  <td id="mark:name">foo</td>
  <td>
   <a href="mailto:foo@mail.com" id="mark:email">foo@mail.com</a>
  </td>
 </tr>
</table>

The following is the presentation logic file. In the presentation logic, you should detect whether odd or even line in the iteration.

Presentation Logic (example2.plogic):

/*
 * an element which is marked by 'id="mark:list"'
 *  - print value of a variable 'color' as bgcolor attribute value.
 */
#list {
  attrs:  "bgcolor" color;
  logic: {
    @members.each_with_index do |member, i|
      color = i % 2 == 0 ? '#FFCCCC' : '#CCCCFF';
      _stag    # start tag
      _cont    # content
      _etag    # end tag
    end
  }
}

/*
 * an element which is marked by 'id="mark:name"':
 *  - print value of member[:name] as content of the element.
 */
#name {
  value: member[:name];
}

/*
 * an element marked by 'id="mark:email"':
 *  - print value of member[:email] as contentn of the element. 
 *  - print "mailto:" and member[:email] as href attribute value.
 */
#email {
  value: member[:email];
  attrs: "href" "mailto:#{member[:email]}";
}

(Don't forget the semicolon at the end of line especially for Ruby user!)

You will find that there is no HTML tag in the presentation logic and no logic in the presentation data. That is to say, Kwartz can separate presentation logic from presentation data.

compilation
$ kwartz -p example2.plogic example2.html > example2.rhtml
output script
<table>
<%     @members.each_with_index do |member, i| %>
<%       color = i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'; %>
 <tr bgcolor="<%= color %>">
  <td><%= member[:name] %></td>
  <td>
   <a href="<%= "mailto:#{member[:email]}" %>"><%= member[:email] %></a>
  </td>
 </tr>
<%     end %>
</table>

1-5   Other Examples of Presentation Logic

Kwartz enables you to write complex presentation logic natulally. This section shows some examples. See Presentation Pattern Catalog for details.

  • Iterate an element.
    #list {
      logic: {
        for member in @members
          _stag
          _cont
          _etag
        end
      }
    }
    
    Or
    #list {
      logic: {
        for member in @members
          _elem     # equivarent to _stag + _cont + _etag
        end
      }
    }
    
  • Iterate only contents. This is useful for <dl></dl>.
    #list {
      logic: {
        _stag
        for member in @members
          _cont
        end
        _etag
      }
    }
    
  • Replace content of element by expression value.
    #list {
      logic: {
        _stag
        print expr
        _etag
      }
    }
    
    Or
    #list {
      value: expr;
    }
    
  • Replace element by exression value
    #list {
      logic: {
        print expr
      }
    }
    
    Or
    #list {
      elem:  expr;
    }
    
  • Delete start-tag and end-tag, and leaves content only.
    #list {
      logic: {
        _cont
      }
    }
    
  • Delete element. This is useful for delete dummy data.
    #list {
      logic: {
      }
    }
    
  • Replace element with other element.
    #list {
      logic: {
        _element(foo)  # expand other element marked with name 'foo'
      }
    }
    
  • Replace element with other element's content.
    #list {
      logic: {
        _content(foo)  # expand content of other element
      }
    }
    
  • Include complex presentation logics.
    #list {
      logic: {
        i = 0
        for member in @members
          i += 1
          if i % 2 == 0
            color = '#FFCCCC'
          else
            color = '#CCCCFF'
          end
          _elem    # '_elem' is equivarent to _stag + _cont + _etag
        end
      }
    }
    

It is very important that tag/attribute names don't appear in presentation logic at all. This way, you don't need to change presentation logic files even if the tag/attribute names are changed in the presentation data.

Kwartz separates presentation logic from presentation data and main program.