DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Coding
  3. Java
  4. Java Templating With Rocker

Java Templating With Rocker

This tutorial will dive into templating with Rocker, a Java 8 template engine designed to be statically typed, and the pros and cons of using this tool.

Michael Scharhag user avatar by
Michael Scharhag
·
May. 15, 18 · Tutorial
Like (2)
Save
Tweet
Share
13.98K Views

Join the DZone community and get the full member experience.

Join For Free

In this post, we will have a quick look at Rocker, a statically typed and fast Java 8 template engine.

Required Dependencies

To get started with Rocker, we need to add the following dependencies to our project:

<dependency>
    <groupId>com.fizzed</groupId>
    <artifactId>rocker-runtime</artifactId>
    <version>0.24.0</version>
</dependency>

<!-- for hot-reloading support in development -->
<dependency>
    <groupId>com.fizzed</groupId>
    <artifactId>rocker-compiler</artifactId>
    <version>0.24.0</version>
</dependency>


We also need the Rocker Maven plugin, which converts Rocker templates to Java code:

<build>
    <plugins>
        <plugin>
            <groupId>com.fizzed</groupId>
            <artifactId>rocker-maven-plugin</artifactId>
            <version>0.24.0</version>
            <executions>
                <execution>
                    <id>generate-rocker-templates</id>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>


Creating the First Templates

We will start with a simple example containing two Rocker templates and a Java class.

In the first template (main.rocker.html), we define the basic page structure:

@args (String title, RockerBody content)

<html>
  <head>
    <title>@title</title>
  </head>
  <body>
    @content
  </body>
</html>


This template has two parameters: The page title and a RockerBody element named content. The content parameter is basically a sub-template that is added to the <body> tag.

Now we create another template (basic.rocker.html) that defines the content that is passed to our first template:

@args (String name)

@views.main.template("Basic example") -> {
    <h1>Hello @name!</h1>
}


This template has a single name parameter that is written to a <h1> tag. We reference the first template (main.rocker.html) with @views.main and use the template(..) method to render it. "Basic example" will be passed as title parameter. The content parameter is defined within the curly braces.

Rendering Rocker templates

Rocker templates are converted to Java code. This can be done using the following Maven command:

mvn generate-sources


This generates a Java class for each template in the target/generated-sources/rocker directory.

Now we can render our templates using Java code:

public class Main {

    public static void main(String... args) throws Exception {

        // The template "basic.rocker.html" got converted to the class named "basic"
        // which is located in the "views" package

        String result = views.basic.template("John")
            .render()
            .toString();

        System.out.println(result);
    }
}


The output we get looks like this:

<html>
    <head>
        <title>Basic example</title>
    </head>
    <body>
        <h1>Hello John!</h1>
    </body>
</html>


A bit of a problem with this approach is that you need to run mvn generate-sources everytime you make a change in your template files. Also note, that your Java code might not compile if the code generation fails because you have an issue in one of your templates.

Another possible approach is to use hot reloading and reference the templates dynamically via file names.

In this case, the Java code looks like this:

public class Main {

    public static void main(String... args) throws Exception {

       // Enable hot reloading
    RockerRuntime.getInstance().setReloading(true);

    // Reference via string instead of using generated code
    String result = Rocker.template("views/basic.rocker.html")
        .bind("name", "John")
        .render()
        .toString();

    System.out.println(result)
    }
}


The output we get is exactly the same.

Expressions

Assume we have a simple User class that contains the methods getFirstName() and getLastName(). In the following example we see how we can work with the User object in a Rocker template:

@import com.mscharhag.rockerexample.*

@args (User user)

@views.main.template("Expressions") -> {
    <ul>
        <!-- first name -->
        <li>@user.getFirstName()</li>

        <!-- first three letters of first name -->
        <li>@user.getFirstName().substring(0, 3)</li>

        <!-- first name and last name -->
        <li>@user.getFirstName() @user.getLastName()</li>

        <!-- using a variable-->
        @name => {
            @user.getFirstName() @user.getLastName()
        }
        <li>@name</li>

    </ul>
}


Conditions

Rocker supports the standard Java if-else flow structure as the following example shows:

@import com.mscharhag.rockerexample.*

@args (User user)

@views.main.template("Conditions") -> {
    @if (user.getFirstName().length() > 10) {
        <p>Long first name</p>
    } else {
        <p>short first name</p>
    }
}


Loops

Rocker templates support different forms of loops:

@import com.mscharhag.rockerexample.*
@import java.util.*

@args (List<User> users)

@views.main.template("Loops") -> {
    <ul>
        <!-- standard for loop -->
        @for (int i = 0; i < users.size(); i++) {
            <li>@users.get(i).getFirstName()</li>
        }

        <!-- standard 'for each' loop -->
        @for (User user : users) {
            <li>@user.getFirstName()</li>
        }

        <!-- for each loop with additional loop information

        <li>0: John, first: true, last: false</li>
        <li>1: Martin, first: false, last: false</li>
        <li>2: Anna, first: false, last: true</li>
        -->
        @for ((i, user) : users) {
            <li>@i.index(): @user.getFirstName(), first: @i.first(), last: @i.last()</li>
        }

    </ul>
}


The last loop is a special variation of Java's for-each loop. A second index parameter (named i in the example) can be used to access current iteration information.

Conclusion

Rocker can be definitively an option if you are looking for a Java template engine. According to the benchmark on the Rocker GitHub repository, Rocker is a lot faster than other Java template engines like Freemarker or Velocity. The comprehensive documentation is another good point to mention.

The fact that Rocker compiles to Java and allows you to pass data to views in a typesafe way is quite interesting. On one side this is useful because it helps to reduce bugs. On the other side, the same feature annoyed me a bit, while I was writing the examples. Whenever I made code changes that affected Rocker templates (e.g. by changing the name of a method that was called within a Rocker template) the templates stopped compiling. In some situations, this again stopped my Java code from compiling (because it was using the classes generated by Rocker). This is expected but it can break my preferred workflow of writing Java code first and fixing the templates later. Referencing templates via file names instead of using the generated classes solved this problem (but also throws away the type checking at compile time).

Java (programming language) Template

Published at DZone with permission of Michael Scharhag, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Why Every Fintech Company Needs DevOps
  • Cloud Native London Meetup: 3 Pitfalls Everyone Should Avoid With Cloud Data
  • Top 5 Node.js REST API Frameworks
  • Problems of Cloud Cost Management: A Socio-Technical Analysis

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: