Templates

Templates are used to produce complex textual output such as HTML. Representation as Template objects allows easy composition. Template systems like Freemarker or Velocity can be integrated. Civilian offers an own high-performance template system named CSP.

Introduction

Templates can be used to produce the content of a textual response, most important the content of a HTML response.

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.

The Template class

Templates are represented as objects of class Template. The Template base class itself is abstract and agnostic of the template system used.

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)
In order to print its content, a template object must hold all dynamic data needed to produce the content. The typical work done in a Controller method when processing a request, therefore consists of these steps:
  1. Evaluate request parameters
  2. Gather all required data to produce the response
  3. Create a template object, passing all needed data
  4. Write the template to the response
Like controllers, template objects are constructed to produce a single response and are not reused between different requests.

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);

Integration of Freemarker and Velocity

Freemarker and Velocity are well-established template systems.

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.

CSP Template Engine

Civilian offers an own template system called CSP which stands for Civilian Server Pages. CSP is described in detail in the next chapter.