Let's suppose we are in a Controller method, evaluated the request and gathered all data needed
for the response. In case of a pure data response like a JSON message we can just rely on
methods like Response.writeJson to produce the response content.
Easy.
But in case of HTML output more needs to be done.
The Response class itself offers a TemplateWriter to which we can directly
write the content, in a series of print
calls. But this approach only works for really simple content.
Templates to the rescue!
Templates are a way to describe the static scaffold of a document or content. Dynamic data is intermingled into this scaffold to produce the actual output. The syntax of templates is defined by a template system. These systems also often have a runtime component – a template engine – which, given the data, interprets the template syntax and produces the output.
Civilian uses the Template class to represent template instances. In the following section we describe the architectural implications of this class and how to use it.
Once you have a constructed template, it is is easy to write it to the response:
Template template = ...
Response response = ...
response.writeTemplate(template); // 1) calls 2)
// or
template.print(response.getWriter()); // 2)
The self-contained nature of templates has an important architectural implication. Template objects can itself be passed to other templates. That allows to build complex response content by composing it from simpler parts.
Template menuTemplate = ...
Template contentTemplate = ...
Template pageTemplate = new PageTemplate(menuTemplate, contentTemplate);
response.writeTemplate(pageTemplate);
Both libraries provide own template classes. Given a Freemarker or Velocity template object you can easily produce response content by writing the template to the TemplateWriter of the response.
To turn a Freemarker or Velocity template into a Civilian template you can additionally use
FreemarkerTemplate and VelocityTemplate. They are simple wrappers for their native
counterpart and constructed given a Freemarker or a Velocity template object plus their respective data models.
Integration of other template systems would follow the same pattern.