## XHTML Template Processing

Many web application frameworks provide a way of templating, write some boilerplate HTML and fill in the details at the moment a page is requested. Apart from that, a page may contains lots of external scripts, stylesheets, images and fonts. For these two tasks libzeep comes with a `template_processor` class.

#### loading

Starting with the second task just mentioned, the `template_processor` takes a `docroot` parameter in its constructor. This docroot is the location on disk where files are located. But it is also possible to build libzeep with in-memory resources by using `mrc`. Have a look at the example code for usage.

The `load_file` member of `template_processor` loads a file from disk (or compiled resources), the `file_time` member can be used to get the file time of a file. This can be used to generate `304 not modified` replies instead.

The `load_template` member loads a template file from docroot and parses the XML contained in this file into a `zeep::xml::document`.

#### templates

Since we're using a XML parser/library to load template, they should be strict XMTML. It is possible to make these files somewhat HTML 5 like by adding the doctype

    <!DOCTYPE html SYSTEM "about:legacy-compat">

The tags inside a template can be processed using a tag_processor. Tag processors are linked to element and attributes in the template using XML namespaces.

The method `create_reply_from_template` can be used to convert a template into a reply using the data store in a `scope`.

#### tag processing

Libzeep comes with two tag_processor implementations, the first `tag_processor_v1` is a legacy one and should probably not be used in new code. The second, `tag_processor_v2`, is inspired by https://www.thymeleaf.org.

### Using `el` script

`el` is the abbreviation for Expression Language. It is a script language that tries to be like http://en.wikipedia.org/wiki/Unified_Expression_Language. libzeep comes with code to evaluate `el` expressions. The language has the concept of variables and these can be created in the C++ code using the `json::element` class. Variables created this way are then stored in a `scope` object and passed along to the processing code.

To give an example:

    zeep::json::element ints{
        {
            { "value", 1 }
        },
        {
            { "value", 2 }
        }
    };
    scope.put("ints", ints);

| Fill a scope with an array of objects, each object having one element

And then you can process some `expression language` construct like this:

    auto s = zeep::http::evaluate_el(scope, "|1: ${ints[0].value}, 2: ${ints[1].value}|");

And if you then print out the result it should give you something like:

    "1: 1, 2: 2"

##### `el` syntax

Most often you will use simple expressions:

Table 3.2. Simple expressions

expression | evaluates to
--- | ---
`${ ... }` | variable
`*{ ... }` | selection variable (lookup is done in the scope of variables that were selected with `z:select`, v2 processor only )
`@{ ... }` | link URL
`~{ ... }` | fragment
`#{ ... }` | message (not supported yet in libzeep)

The language has literals:

Table 3.3. Literals

expression | evaluates to
--- | ---
`'my text string'` | Text literal
`0 3.14` | Numeric literal, note that scientific notation is not supported
`true false` | Boolean literal
`null` | Null literal
`user greeting` | token

Text operations supported are:

Table 3.4. Text operations

construct | description
--- | ---
`'a' + ' b'` | concatenation, result is 'a b'
`|hello ${user}|` | literal substitution, if variable user contains 'scott', result is 'hello scott'

Operators:

Table 3.5. operators

operators | type
--- | ---
`+ - * / %` | binary operators for standard arithmetic operations
`-` | unary operator, minus sign
`and or` | binary operators for standard boolean operations
`! not` | unary operators, negate
`> < >= <= gt lt ge le` | operators to compare values
`== != eq ne` | operators to check for equality
`a ? b` | conditional operator: if a then return b else null
`a ? b : c` | conditional operator: if a then return b else return c
`a ?: b` | conditional operator: if a then return a else return b

When using variables, accessing their content follows the same rules as in Javascript. Arrays have a member function `length`.

A few predefined utility objects are predefined. These are #dates, #numbers, #request and #security.

Table 3.6. Predefined objects and their methods

object.method | Description
--- | ---
`#dates.format(date,format)` | This method takes two parameters, a preferrably ISO formatted date and a format string. The result will be the output of `std::put_time`.

`#numbers.formatDecimal(number,int_digits,decimals)`

This method takes up to three parameters, a number that needs to be formatted, an int_digits parameter that specifies the minimum number of integral digits to use and a decimals parameter that specifies how many decimals to use.

The number is formatted using the locale matching the language specified in the Accept HTTP request header. However, if that locale is not available the default locale is used.

Defaults for int_digits is 1 and decimals is 0.

Example output: `${#numbers.formatDecimal(pi,2,4)}` is `03.1415` when the locale to use is en_US.

`#numbers.formatDiskSize(number,decimals)`

This method takes up to two parameters, a number that needs to be formatted, and a decimals parameter that specifies how many decimals to use.

The number is divided by 1024 until it fits three int digits and the suffix is adjusted accordingly.

Default for decimals is 0.

Example output: `${#numbers.formatDiskSize(20480,2)}` is `2.00K` when the locale to use is en_US.

`#request.getRequestURI()` | Returns the original URI in the HTTP request.
`#security.authorized()` | Returns whether the uses has successfully logged in.
`#security.username()` | Returns the username for the current user.
`#security.hasRole(role)` | Returns whether the uses has the role as specified by the parameter.

### tag_processor_v1

This tag_processor works on tags, mostly. As opposed to tag_processor_v2 which works on attributes mainly. The tags are in a separate XML namespace. You can change this name space using the `ns` parameter in the constructor, the default is `http://www.hekkelman.com/libzeep/m1`.

There are several predefined processing tags which are summarized below. There used to be also a way to add your own processing tags using an `add_processor` method but that has been dropped.

Table 3.7. List of predefined processing tags

tag name (without prefix) | Description | Example
--- | --- | ---
include | Takes one parameter named `file` and replaces the tag with the processed content of this file | `<zeep:include file="menu.xhtml"/>`

if

Takes one parameter named `test` containing an `el` script. This script is evaluated and if the result is not empty, zero or false, the content of the `if` tags is inserted in the output. Otherwise, the content is discarded.

    <zeep:if test="${not empty name}">
      Hello ${name}
    </zeep:if>

iterate

Takes two parameters, `collection` which contains an `el` script that evaluates to an array `el::object` and a name in `var`. The content of the `iterate` tag is included for each value of `collection` and `var` will contain the current value.

    <ul><zeep:iterate collection="${names}" var="name">
      <li>${name}</li>
    </zeep:iterate></ul>

for

Takes three parameters. The parameters `begin` and `end` should evaluate to a number. The parameter `var` contains a name that will be used to hold the current value when inserting the content of the `for` tag in each iteration of the for loop between `begin` and `end`.

    <zeep:for begin="1" end="3" var="i">
      ${i},
    </zeep:for>

number

Format the number in the `n` parameter using the `f` format. This is limited to the formats `'#.##0'` and `'#.##0B'` for now. The first formats an integer value using thousand separators, the second tries to format the integer value in a power of two multiplier (kibi, mebi, etc.) with a suffix of `B`, `M`, `G`, etc.

    <zeep:number n="1024" f="0.00#B"/>
    Will output 1K

options

This tag will insert multiple `<option>` tags for each element in the `collection` parameter. This `collection` paramter can contain an array of strings or it can contain an array of `el::object`. In the latter case, you can specify a `value` and `label` parameter to name the value and label fields of these objects. A `selected` parameter can be used to select the current value of the options.

    <zeep:options collection="${names}"
      value="id" label="fullName" selected="1" />

option

Generate a single `<option>` tag with a value as specified in the `value` parameter. If `selected` evaluates to the same value as `value`, the option is selected. The content of the `<option>` tag is inserted in the final tag.

    <zeep:option value="1" selected="${user}">
      John Doe
    </zeep:option>

checkbox

Create an `<input>` tag with type `checkbox`. The parameter `name` is used as name attribute and the parameter `checked` is evaluated to see if the checkbox should be in checked mode.

    <zeep:checkbox name='cb1' checked='${true}'>
      Check me
    </zeep:checkbox>

url

The url processing tag creates a new variable in the current scope with the name as specified in the `var` parameter. It then creates a list of all original HTTP parameters for the current page. You can override these parameter, and add new ones, by adding `<param>` tags in the `<url>` tag.

    <zeep:url var="next">
      <zeep:param name='page' value='${page + 1}'/>
    <zeep:url>
    <a href="${next}">Next page</a>

param | see `url` above. |

embed

This tag takes the content of the `var` parameter which should contain valid XML and puts the processed value in the document.

    <zeep:embed var="&lt;em&gt;hello, world!&lt;/em&gt;"/>

### tag_processor_v2

Tag processor version 2 is an implementation of the documentation for Thymeleaf. This documententation is a bit sparse, for now you might be better off reading the one at the Thymeleaf site.

There are some notable differences between Thymeleaf and libzeep though, libzeep does not support the concept of `messages` yet, so using this for localization is not going to work. Furthermore, the Thymeleaf library is written in Java and assumes all data constructs are Java object. Of course that is different in libzeep.

##### tags

There is only one tag this tag processor processes, which is `<z:block>`, for the rest this processor only processes attributes.

##### attributes

Some attributes are treated special, these are listed below. For the other tags the general rule is that if the tag has the prefix for the `v2` namespace, the value of the attribute will be evaluated and the result will be placed in an attribute without the prefix. Possibly overwriting an already existing attribute with that name.

So, e.g. if you have

    <span id="one" z:id="${id}"/>

and the variable `id` contains `'two'` the result will be

    <span id="two"/>

##### special attributes

Table 3.8. processed attributes

attribute | remarks
--- | ---
`assert` | If the value of this attribute evaluates to `true`, an exception will be thrown.

`attr`

The value of this attribute is an expression consisting of one or more comma separated statements that assign a value to an attribute. e.g.

    <img z:attr="width=${width},height=${height}"/>

will result in the following when the value of the variables `width` and `height` is `100`.

    <img width="100" height="100/>

`classappend`, `styleappend` | The value is evaluated and the result is appended to the `class` or `style` attribute respectively.

`each`

The expression in the value should have a name for a variable, optinally followed by a comma and the name for an iterator-info variable. Then a colon followed by an expression whose result after evaluation is an array.

The tag containing this attribute will be repeated as many times as there are elements in the array. Each copy will then be evaluated with the name value set to the current value in the array.

Example, consider this snippet

    <tr z:each="a, i: ${ { 'aap', 'noot', 'mies' } }">
      <td z:text="${i.count}"/>
      <td z:text="${a}"/>
    </tr>]

will result in

    <tr>
      <td>1</td>
      <td>aap</td>
    </tr>
    <tr>
      <td>2</td>
      <td>noot</td>
    </tr>
    <tr>
      <td>3</td>
      <td>mies</td>
    </tr>

The iterator-info variable can be used to get info about the current value.

Table 3.9. iterator members

name | description
--- | ---
count | counting number starting at one.
index | counting number starting at zero.
even | boolean indicating whether this is an even element
odd | boolean indicating whether this is an odd element
size | size of the total array/collection
first | boolean indicating the first element
last | boolean indicating the last element
current | the value of the current element

`if`, `unless` | The attribute value is evaluated and if the result is `true` respectively `false` the containing tag is preserved, otherwise it is deleted.

`include`, `insert`, `replace`

These three statements are used to pull in fragments of markup. The value of the attribute is evaluated and should contain a fragment specification. The contents of this fragment are then copied to the destination. The three attributes differ in the following way:

insert

  The complete fragment is inserted inside the body of the containing tag

replace

  The complete fragment is replaces the containing tag

include

  The content of the fragment is inserted inside the body of the containing tag

Example, when the fragment is `<span z:fragment="f">hello</span>` the following markup:

    <div z:insert="~{::f}/>
    <div z:replace="~{::f}/>
    <div z:include="~{::f}/>

will result in:

    <div><span>hello</span></div>
    <span>hello</span>
    <div>hello</div>

`inline`

The processor processes occurrences of [[ ... ]] or [( ... )] by evaluating what is in between those brackets.

    <div>Hello, [[${name ?: 'world'}]]</div>

will result in (when name = 'scott'):

    <div>Hello, scott</div>

Using this attribute, you can do even more fancy things. If the value of this attribute is `javascript`, the replacement will be valid in a javascript context by properly quoting double quotes e.g. And it will process commented values properly, as in:

    <script z:inline='javascript'>let x = /*[[${var}]]*/ null;</script>

Might result in:

    <script>let x = "He said \"bla bla bla\"";</script>

If the inline attribute has value `text`, the whole body of the tag will be evaluated as `el`.

`switch`, `case`

Example:

    <div z:switch="${user.role}">
    	<span z:case="'admin'">Admin</span>
    	<span z:case="*">Some other user</span>
    </div>

`text`, `utext`

The simplest, replace the body of the tag with the result of the evaluation of the content of this attribute.

    <span z:text="${name}"/>

Will result in:

    <span>scott</span>

The `text` variant will quote special characters like <, > and &. The `utext` variant will not, but beware, if the result is not valid XML an exception is thrown.

`with`

Assign a value to a variable. Example:

    <div z:with="n=${name}">
    	<span z:text="${n}"/>
    </div>