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