Qute: a Template Engine for Quarkus applications

Qute is a templating engine designed specifically for Quarkus. You can use this template engine in a variety of projects but the most common use case is to provide a View to JAX-RS Resouces.

There are mainly two options to use Qute with JAX-RS:

  • Injecting the Template name in your JAX-RS Endpoint: This is the simplest option that we will show in this article
  • Injecting a Type-Safe checked Template in your JAX-RS Endpoint. This option is more advanced although it allows more flexibility

Let’s start by creating a new Project which includes the dependencies we need.

Create your Qute Project

Firstly, create your project with any tool of your like. For example, if you are using the on-line initializer (https://code.quarkus.io) make sure to include the RESTEasy Qute dependency:

quarkus qute tutorial

Your project now includes the following dependency in pom.xml::

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-resteasy-qute</artifactId>
</dependency>

In order to use Qute, we will be placing templates into the folder src/main/resources/templates where they are automatically picked up by Quarkus. Therefore, creare the following folder first:

$ mkdir src/main/resources/templates

Next, edit the file src/main/resource/templates/greeting.html with the following content:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Qute Example</title> 
</head>
<body>
    <p>Good Morning {name ?: "user"}!</p>
</body>
</html>

{name} is a value expression that is evaluated when the template is rendered and will be resolved against the current context object.

It’s important to note that you won’t access the greeting.html page directly. On the other hand, you will access the Endpoint which references this template. Next, create the following GreetingResource Class with this content:

package com.sample.greeting;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import io.quarkus.qute.Template;
import io.quarkus.qute.TemplateInstance;

@Path("/greet")
public class GreetingResource {

    @Inject
    Template greeting;

    @GET
    @Produces(MediaType.TEXT_HTML)
    public TemplateInstance get(@QueryParam("name") String name) {
        return greeting.data("name", name);
    }

}

Here is the project tree:

src
├── main
│   ├── docker
│   ├── java
│   │   └── com
│   │       └── sample
│   │           ├── greeting
│   │               └── GreetingResource.java
│   └── resources
│       ├── application.properties
│       ├── META-INF
│       │   └── resources
│       │       └── index.html
│       └── templates
│           └── greeting.html

To test our application, simply request the “/greet” endpoint as follows:

quarkus qute template

If you provide a value for {name} , it will be printed in the Greeting Message.

Displaying data in Tabular format

A common requirement for UI, is to display a list of data in tabular format. You can accomplish this by returning a List of Objects on the backend and using in your front-end some tags to iterate over the objects. let’s see how to do that with Qute Template engine.

Create a file src/main/resource/templates/time.html with the following content:

<!DOCTYPE html>
<html>
{#include base.html}
{/include}
<body>
    <h2>Available data formats</h2>

    <table class="blueTable">
        <thead>
        <tr>

            <th>Name</th>
            <th>Description</th>
            <th>Wiki link</th>
        </tr>
        </thead>
        <tbody>
        {#for item in data}
        <tr>
            <td>{item.name}</td>
            <td>{item.description}</td>
            <td><a href="{item.wiki}">{item.wiki}</a></td>
        </tr>
        {/for}
        </tbody>
    </table>
{#include footer.html}
{/include}    
</body>
</html>

Within this HTML page there are three main elements:

  • The include base.html directive allows to include an header for your template. Within the base.html file we will add some CSS for rendering our HTML page
  • Within the body, we are iterating over the “data” element which we will place in the Request from within our Template
  • The include footer.html page is simply a static footer message for our page.

For the sake of brevity, we will not include here the header/footer HTML pages which are available in the source code for this tutorial.

Next, let’s code our TimeEndpoint which produces a List of TimeFormat Objects:

@Path("/time")
public class TimeResource {

    @Inject
    Template time;

    @GET
    @Produces(MediaType.TEXT_HTML)
    public TemplateInstance get() {
        List<TimeFormat> data = new ArrayList<>();
        data.add(new TimeFormat("UTC", "Western European Time"));
        data.add(new TimeFormat("UT", "Universal Time"));
        data.add(new TimeFormat("GMT", "Greenwich Time"));
        return time.data("data", data);
    }


    @TemplateExtension
    static String wiki(TimeFormat  data) {
        return "https://en.wikipedia.org/w/index.php?search="+data.getName()+"&fulltext=Search";
    }

}

The mechanism for producing a TemplateInstance should be familiar to you right now. Let’s focus on the data that is returned by the get() method. This method returns a List of TimeFormat objects:

public class TimeFormat {
    String name;
    String description;

   // Getter/Setters
}

Please note, this Class does not include the “wiki” Property that we print in the Template. Why? because we want to show how to use a @TemplateExtension. You can use a @TemplateExtension to add extra properties which are not available in your Java Beans.

In our example, the property “wiki” will be calculated dynamically in the method decorated with @TemplateExtension.

Here is the project tree for the new example:

src
├── main
│   ├── docker
│   ├── java
│   │   └── com
│   │       └── sample
│   │           └── time
│   │               ├── TimeFormat.java
│   │               └── TimeResource.java
│   └── resources
│       ├── application.properties
│       ├── META-INF
│       │   └── resources
│       │       └── index.html
│       └── templates
│           ├── base.html
│           ├── footer.html
│           └── time.html

Finally, here is how your http://localhost:8080/time View looks like in the browser:

qute tutorial

Checking the available templates

Finally, it’s worth mentioning that you can check the list of available templates from the Dev UI page at: http://localhost:8080/q/dev/

There, you will be able to check the configuration of your Templates and to render them in your Browser:

quarkus template

Conclusion

In this tutorial we have learned how to use Qute as template engine for Quarkus. We have some basic examples of solving context expressions and more advanced examples using extensions.

You can find the full code for this tutorial here: https://github.com/fmarchioni/mastertheboss/tree/master/quarkus/front-end/qute

Found the article helpful? if so please follow us on Socials