Template Interpreter

The TemplateInterpreter is a central component which adds the capability to generate highly dynamical content. It is heavily used int the printing and the web module.

Click here to browse the API documentation of the current version.

The defaultr implementation of the TemplateInterpreter makes heavy useage of the ExpressionInterpreter component.

You can easily use the TemplateInterpreter from your own code. Here's a simple example.
try {
  // creating factory
  TemplateInterpreterFactory tif = new DefaultTemplateInterpreterFactory();
  // creating template interpreter
  TemplateInterpreter interpreter = createTemplateInterpreter();
  // creating expression context
  TemplateContext ctx = tif.createTemplateContext(new HashMap(), FormatHelper.createInstance(Locale.US));
  ctx.setProperty("word", "UJAC");
  System.out.println("expression result: " + interpreter.execute("The length of the word ${word} is ${word length}", properties));
} catch (TemplateException ex) {
  // Oops, something went wrong ...
  ex.printStackTrace();
}

Templates may consist of simple texts and expressions which are evaluated and merged together as a text:
Happy birthday ${customer.salutation} ${customer.name}.
The default interpreter cuts this template code into 4 pieces: The text 'Happy birthday ', the expression '${customer.salutation}', a ' ' and finally the expression '${customer.name}'. When executing the template it evalates each token and concatenates the results.

Templates can also contain control and loop statements which enable the evaluation of complex contents. Here's a short example:
_foreach_(customer ${customers} 'even' 'odd')
    <tr class="${customerStyle}">
        <td>${customer.name}</td>
        <td>${customer.firstName}</td>
        <td>${customer.dateOfBirth}</td>
        <td>_if_(customer.sex == 'M')male_else_female_endif_</td>
    </tr>
_endfor_
Loops over the elements of the sequence, specified by the expression ${customers}. prints the body between _foreach_(...) and _endfor_ for each element in the sequence.
The nested _if_ statement makes a boolean evaluation of the text within the parentheses and prints its body or the else body, dependent on this result.

Even procedures can be defined and used, which enables the reuse of template parts within a template.
_procedure_ printAddress(address, style)
    <tr class="${style}">
        <td>${address.street}</td>
        <td>${address.zipCode}</td>
        <td>${address.residence}</td>
        <td>${address.country}</td>
    </tr>
_endproc_
_callproc_(${customer.mainAddress}, 'odd')
_foreach_(address ${customer.addresses} 'even' 'odd')
	_callproc_(${address} ${addressStyle})
_endproc_
Defines a procedure which prints an address. This procedure is executed later on for each defined customer address.

Procedures may also be called recursively, which enables the output of complex data structures like trees:
_procedure_ printItem(item, separator)
	_define_(count, ${count + 1})
	${item.name} #${count}\n
	_if_(item.childs isDefined)
		_foreach_(child ${item.childs})
			${separator}_callproc_(printItem, ${child}, ${separator + ' '})
		_endfor_
	_endif_
_endproc_

_define_(count, 0)
_callproc_(printItem, ${rootNode}, ' ')
Prints the tree, specified by the property ${rootNode} by using the procedure 'printItem'. This procedure calls itself for each child of the node that's passed to it as argument.

If you like to log from your template code, thats no problem:
_log_('debug', 'debug output')
_log_('info', 'information output')
_log_('warn', 'prints a warning')
_log_('error', 'error occurred')
_log_('fatal', 'this is no good!!')
Prints entries with various levels to the log. The logging is performed by the commons-logging framework. The output heavily depends on the logging framework which is used by commons-logging.