Jtwig Core

Within this section one will detail how to work with Jtwig at it's core API. As a template engine, Jtwig has three main concepts, they are Environment, Resource and Model.

Output = (Environment, ResourceReference, Model)

The Environment contains all Jtwig configurations and predefined behaviour, this includes possible extensions that might be added. The ResourceReference contains the intermediate Jtwig representation, also known as Template and the Model is the container of key and value pairs which combined with the Template generates the output. We can break it down in the following way.

Template = (Environment, ResourceReference)

Where, basically, the Template is the combination of the Environment with the ResourceReference. This has special meaning when extensions are added and means some intermediate representations don't mean anything without the proper extension added to the Environment. Note that, one will detail about Extensions later on.

Output = (Template, Model)

Hello World Example

Let's now have a look at the famous Hello World program in Jtwig using the core API.

// Environment
EnvironmentConfiguration configuration = new DefaultEnvironmentConfiguration();
EnvironmentFactory environmentFactory = new EnvironmentFactory();
Environment environment = environmentFactory.create(configuration);

// Resource
ResourceReference resource = new ResourceReference(
    ResourceReference.STRING, 
    "Hello {{ token }}!"
);

// Template
JtwigTemplate jtwigTemplate = new JtwigTemplate(environment, resource);

// Model
JtwigModel model = JtwigModel.newModel().with("token", "World");

// Output
String output = jtwigTemplate.render(model);

As one can see, the way Jtwig core API is built follows the same concepts mentioned before, where the Enviornment and ResourceReference are first instantiated in order to create the JtwigTemplate, which when combined with the JtwigModel generates the output.

JtwigTemplate API

The JtwigTemplate implementation comes with API to simplify some application code. Namely the static methods inlineTemplate, fileTemplate and classpathTemplate allows one to, respectively, load a Jtwig template directly from a String, file or classpath. Using the previous example, one can simplify the code using the inlineTemplate method, as the below example shows.

// Environment
EnvironmentConfiguration configuration = new DefaultEnvironmentConfiguration();

// Template
JtwigTemplate jtwigTemplate = JtwigTemplate
    .inlineTemplate("Hello {{ token }}!", configuration);

// Model
JtwigModel model = JtwigModel.newModel().with("token", "World");

// Output
String output = jtwigTemplate.render(model);

JtwigModel API

Jtwig Model can be seen as a map of properties, which will then be used to render the template. The keys can only be valid Java identifiers as mentioned before.

JtwigModel model = JtwigModel.newModel()
     .with("variable", "Jtwig")
     .with("secondVariable", 1);

Processing Pipeline

Parsing Stage

The way Jtwig produces the final result is through a well defined processing pipeline. At start of this whole processing is the parsing stage. The parsing stage is where Jtwig parses a file producing a tree of nodes based of the Jtwig Abstract Syntax Tree. This tree is composed of content nodes and expressions. As mentioned before expressions are evaluated to values, and where content nodes are evaluated to streamable content. By content nodes we mean all the Jtwig tags and raw text defined in the template.

Lazy loading nested resources

In Jtwig nested resources, which can be referred using include, extends, embed and import constructs, are loaded in rendering time (lazy loaded) as the path expression needs to be evaluated first.

Caching resources

Another concept included in the parsing stage is the resource caching mechanism. By default Jtwig will cache the parsed resources in memory in a persistent fashion, that means, for the lifetime of the JVM, resources are only parsed once.

Rendering Stage

The next stage is the rendering stage. Each content node in the parsed tree is processed into streamable content. Before each content node being rendered the associated escape mode is initialised. This will then be used to serialize the output. The Jtwig serializer is capable of escaping content based on a specified strategy. Supported escape modes were already specified in the autoescape tag definition.

Expression Evaluation

During the rendering stage, expressions are evaluated, for example, to perform the Jtwig control flow. An important aspect of this evaluation mechanism is a special type introduced by Jtwig, that is, the Undefined value. It's a singleton used to specify when the result of evaluating an expression is undefined. For example, accessing an undefined array index or evaluating an undefined variable.