Jtwig tutorial

This is an introductory tutorial of the Jtwig Java template engine. We introduce the Jtwig template engine and create several console and web applications. Maven is used to build our examples. NetBeans is used to manage the applications.

Jtwig is a modern template engine for the Java programming language. It is modular, configurable, and easy to use template engine. It was inspired by the Django's template engine. Jtwig's home page is jtwig.org.

A template engine combines static data with dynamic data to produce content. A template is an intermediate representation of the content; it specifies how the output will be generated.

The advantages of a template engine are:

Jtwig is not restricted to templates for HTML pages; it can be used for plain text as well.

Console applications

The first four applications are console applications. We create new Maven Java Applications in NetBeans. They use the following Maven build file:

Excerpt from pom.xml
<repositories>
    <repository>
        <id>jcenter</id>
        <url>https://jcenter.bintray.com/</url>
    </repository>
</repositories>    

<dependencies>
    <dependency>
        <groupId>org.jtwig</groupId>
        <artifactId>jtwig-core</artifactId>
        <version>5.58</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.21</version>
    </dependency>
</dependencies>    

In the Maven pom.xml file, we specify the repository for Jtwig and the jtwig-core and slf4j-simple dependencies.

Variables

In the first application, we explore the Jtwig set command. The set command allows to specify an assignment operation inside a Jtwig template. It assigns the result of an expression to the specified variable.

Java console project structure in NetBeans
Figure: Java console project structure in NetBeans

This is the project structure in NetBeans.

ConsoleJtwigEx.java
package com.zetcode.client;

import org.jtwig.JtwigModel;
import org.jtwig.JtwigTemplate;

public class ConsoleJtwigEx {

    public static void main(String[] args) {

        JtwigTemplate template
                = JtwigTemplate.classpathTemplate("templates/simple.twig");
        JtwigModel model = JtwigModel.newModel();

        template.render(model, System.out);
    }
}

We create a Java console application that processes the Jtwig template file.

JtwigTemplate template
        = JtwigTemplate.classpathTemplate("templates/simple.twig");

A JtwigTemplate is created. It loads the simple.twig template file located in the src/main/java/resources/templates directory.

JtwigModel model = JtwigModel.newModel();

The JtwigModel is created. The model is the container of key and value pairs which combined with the template generates the output.

template.render(model, System.out);

The render() method creates the final output. It uses the model and outputs to system output.

simple.twig
{% set v = 3 + 3 %}
{{ v -}}

{% set a = [1, 2, 3] %}
{{ a[1] -}}

{% set m = { k1: "apple", k2: "banana"} %}
{{ m["k1"] }}

In the simple.twig file, we define three variables with the set command and display them.

{% set v = 3 + 3 %}

Jtwig code islands begin with {% and end with %}.

{{ v -}}

Jtwig uses {{ and }} to display values of expressions and variables. The - is a optional white space control character. Here it removes the white space after the code island.

6
2
apple

This is the output of the application.

Hello application

In the second application, we pass a variable to the template.

ConsoleJtwigEx2.java
package com.zetcode.client;

import org.jtwig.JtwigModel;
import org.jtwig.JtwigTemplate;

public class ConsoleJtwigEx2 {

    public static void main(String[] args) {
        
        JtwigTemplate template = 
                JtwigTemplate.classpathTemplate("templates/hello.twig");
        JtwigModel model = JtwigModel.newModel().with("name", "Peter");

        template.render(model, System.out);
    }
}

Using the with() method, we pass a variable to the template file.

hello.twig
Hello {{ name }}

In the template, we display the variable.

Hello Peter

This is the output of the example.

Passing list

In the next application, we pass a list of values to the template.

Excerpt from pom.xml
<dependencies>
    <dependency>
        <groupId>org.jtwig</groupId>
        <artifactId>jtwig-core</artifactId>
        <version>5.58</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.21</version>
    </dependency>
    
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>19.0</version>
    </dependency>
    
</dependencies>

In addition to jtwi-core and slf4j-simple libraries, we add the guava library to the project dependencies.

ConsoleJtwigEx3.java
package com.zetcode.client;

import com.google.common.collect.Lists;
import java.util.List;
import org.jtwig.JtwigModel;
import org.jtwig.JtwigTemplate;

public class ConsoleJtwigEx3 {
    
    public static void main(String[] args) {
        
        List<String> names = Lists.newArrayList("Jan", "Peter", "Jane");
        
        JtwigTemplate template = 
                JtwigTemplate.classpathTemplate("templates/friends.twig");
        JtwigModel model = JtwigModel.newModel().with("names", names);

        template.render(model, System.out);
    }    
}

In the code example, we pass a list of names to the template.

List<String> names = Lists.newArrayList("Jan", "Peter", "Jane");

Using Google Guava, we create a list of names.

JtwigModel model = JtwigModel.newModel().with("names", names);

The list is passed to the template.

friends.twig
{% for name in names %}
    {{ name }}
{% endfor %}

Using the for command, we go through the list and display its elements.

Including templates

With the include command, we can include other template files.

Java console project structure in NetBeans 2
Figure: Java console project structure in NetBeans 2

There are three files in the templates directory.

ConsoleEx4.java
package com.zetcode.client;

import org.jtwig.JtwigModel;
import org.jtwig.JtwigTemplate;

public class ConsoleJtwigEx4 {

    public static void main(String[] args) {

        JtwigTemplate template
             = JtwigTemplate.classpathTemplate("templates/main.twig");
        JtwigModel model = JtwigModel.newModel();

        template.render(model, System.out);
    }
}

The example loads the main.twig template, which includes other two templates.

foot.twig
Footer.

This is the foot.twig template.

head.twig
Header.

This is the head.twig template.

main.twig
{% include "classpath:/templates/head.twig" ignore missing %}

Main content.

{% include 'classpath:/templates/foot.twig' ignore missing %}

This is the main.twig template. It includes the foot.twig and head.twig templates.

Header.

Main content.

Footer.

This is the output of the example.

Jtwig servlet example

In the following example, we use Jtwig in a standard Java web application. The application is packed into a war file and deployed on the NetBeans's build-in Tomcat server.

In NetBeans, we create a new Maven Web Application.

Jtwig servlet project structure in NetBeans
Figure: Jtwig servlet project structure in NetBeans

This is the project structure of the Jtwig servlet example in NetBeans.

context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/JtwigServlet"/>

This is the context.xml file.

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.zetcode</groupId>
    <artifactId>ServletJtwigEx</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>    

    <name>ServletJtwigEx</name>
  
    <repositories>
        <repository>
            <id>jcenter</id>
            <url>https://jcenter.bintray.com/</url>
        </repository>
    </repositories>    
    
    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        
        <dependency>
            <groupId>org.jtwig</groupId>
            <artifactId>jtwig-web</artifactId>
            <version>1.52</version>
        </dependency>        
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

This is the pom.xml file. We use the jtwig-web dependency.

JtwigServlet.java
package com.zetcode;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jtwig.web.servlet.JtwigRenderer;

@WebServlet(name = "JtwigServlet", urlPatterns = {""})
public class JtwigServlet extends HttpServlet {

    private final JtwigRenderer renderer = JtwigRenderer.defaultRenderer();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        
        renderer.dispatcherFor("/WEB-INF/templates/index.twig.html")
                .with("greet", "Jtwig servlet example")
                .render(request, response);
    }
}

We set up the servlet and dispatch to the template file. We pass a greet variable to the template.

@WebServlet(name = "JtwigServlet", urlPatterns = {""})

The JtwigServlet is mapped to the application's context root.

index.twig.html
{{ greet }}

The index.twig.html file is located in the WEB-INF/templates directory. The template displays the greet variable.

Jtwig servlet example
Figure: Jtwig servlet example

We show the application output in the Opera web browser. The built-in Tomcat in NetBeans operates on the 8084 port.

Spring Boot

Spring is a popular Java application framework. Spring Boot is a product of an effort to create stand-alone, production-grade Spring based applications with minimal effort.

Spring Boot command line application

In the next application, we integrate Jtwig into a Spring Boot command line application. It is a console application placed into Spring Boot framework.

Spring Boot project structure in NetBeans
Figure: Spring Boot project structure in NetBeans

This is the project structure of the Spring Boot application using Jtwig in NetBeans.

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
            http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.zetcode</groupId>
    <artifactId>SpringBootJtwigConsoleEx</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    
    <repositories>
        <repository>
            <id>jcenter</id>
            <url>https://jcenter.bintray.com/</url>
        </repository>
    </repositories>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.5.RELEASE</version>
        <relativePath />
    </parent>      

    <dependencies>
        
        <dependency>
            <groupId>org.jtwig</groupId>
            <artifactId>jtwig-core</artifactId>
            <version>5.58</version>
        </dependency>        
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>     
              
    </dependencies>
    <name>SpringBootJtwigConsoleEx</name>
</project>

This is the Maven build file. It includes dependencies for Spring Boot and Jtwig.

SpringBootClient.java
package com.zetcode.client;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

@EnableAutoConfiguration
@ComponentScan(basePackages="com.zetcode")
public class SpringBootClient {

    public static void main(String[] args) {

        SpringApplication.run(SpringBootClient.class, args);
    }
}

The SpringBootClient sets up the Spring Boot application. The @EnableAutoConfiguration annotation enable auto-configuration of the Spring Application Context, attempting to guess and configure beans that we are likely to need.

MyRunner.java
package com.zetcode.client;

import org.jtwig.JtwigModel;
import org.jtwig.JtwigTemplate;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MyRunner implements CommandLineRunner {
    
    @Override
    public void run(String... args) throws Exception {

        JtwigTemplate template = 
                JtwigTemplate.classpathTemplate("templates/greet.twig");
        JtwigModel model = JtwigModel.newModel().with("name", "Peter");

        template.render(model, System.out);        
    }
}

The MyRunner is a command line runner for the Spring Boot application. We load the template and render it.

greet.twig
Hello {{name}}!

This is the greet.twig template file.

Hello Peter!

This is the output of the application.

Spring Boot web application

The last example of this tutorial creates a Spring Boot web application utilizing the Jtwig template engine. Note that we are creating a Java SE Maven application in NetBeans, not a Java web Maven application. This is because we have Tomcat embedded into our JAR file.

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.zetcode</groupId>
    <artifactId>SpringBootJtwigWebEx</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    
    <repositories>
        <repository>
            <id>jcenter</id>
            <url>https://jcenter.bintray.com/</url>
        </repository>
    </repositories>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.5.RELEASE</version>
        <relativePath />
    </parent>         

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency> 

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.jtwig</groupId>
            <artifactId>jtwig-spring-boot-starter</artifactId>
            <version>5.55</version>
        </dependency>
        
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.21</version>
        </dependency>           
    </dependencies>    
    
</project>

In the pom.xml file, we have these dependencies: spring-boot-starter, spring-web, jtwig-spring-boot-starter, and slf4j-simple.

MyController.java
package com.zetcode.controller;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@EnableAutoConfiguration
public class MyController {

    @RequestMapping("/{name}")
    public String indexAction (ModelMap model, @PathVariable("name") String name) {
    
        model.addAttribute("name", name);
        return "index";
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(MyController.class, args);
    }
}

This is the controller class for the Spring Boot web application. The controller reads an attribute from the request and puts it into the model. The controller then resolves the mapping to the template file.

index.twig
Hello {{name}}!

This is the index.twig file.

Spring Boot web example
Figure: Spring Boot web example

The Spring Boot starts an embedded Tomcat server, listening on port 8080.

This tutorial was dedicated to the Jtwig template engine. You might also be interested in the related tutorials: FreeMarker tutorial, Java tutorial, Introduction to Play, Introduction to Spark, or Introduction to Stripes.