Over a million developers have joined DZone.

Trimou Templates Introduction

DZone's Guide to

Trimou Templates Introduction

· Java Zone
Free Resource

What every Java engineer should know about microservices: Reactive Microservices Architecture.  Brought to you in partnership with Lightbend.

Trimou is a simple to use and easy to extend templating engine for any Java SE or Java EE application. It is a Mustache template implementation available under the Apache License 2.0. This article is just a brief summary, highlighting some of the most useful features of Trimou. You can read the documentation and study the example code to know more.

The basic set of features of every Mustache implementation are defined in the Mustache specification. Trimou passes all the spec tests (version 1.1.2), except "Section - Alternate Delimiters" from lambdas optional module. But it's not just a Mustache implementation...

Where is the template?

This is a task for a special component called template locator which is able to automatically locate the template contents for the given template identifier. Actually you can have more than one template locator - those with higher priority are called first.

Trimou provides some built-in implementations (classpath, filesystem) which work well in Java SE. ServletContextTemplateLocator (a part of the servlet extension) on the other hand is designed for servlet containers and is able to locate the template anywhere in the web app.

MustacheEngine engine = MustacheEngineBuilder
  .addTemplateLocator(new ServletContextTemplateLocator(10, "/WEB-INF/templates"))
// Pass the template contents as a String
Mustache m1 = engine.compileMustache("my-foo-template", "{{foo}}");
// And now use the locator
Mustache m2 = engine.getMustache("my-template.html");

i18n support

Trimou has a very basic i18n support. It provides three optional resolvers (NumberFormatResolver, DateTimeFormatResolver, ResourceBundleResolver) and one optional lambda (ResourceBundleLambda).

// DateTimeFormatResolver example
MustacheEngine engine = MustacheEngineBuilder
                           .setProperty(DateTimeFormatResolver.CUSTOM_PATTERN_KEY, "DD-MM-YYYY HH:mm")
                           .addResolver(new DateTimeFormatResolver())
Mustache mustache = engine.compileMustache("{{now.formatCustom}}");
Assert.assertEquals("Now: 03-05-2013 22:05", mustache.render(ImmutableMap.<String, Object> of("now", new Date())));

Template inheritance

This feature is not supported in the spec. However it's very important from the maintainability point of view. Trimou basically follows the way mustache.java implements template inheritance. In the extended template, the sections to extend are defined - use $ to identify such sections. In extending templates, the extending sections are defined - again, use $ to identify such sections. Sections to extend may define the default content.

This a template to extend:

  The default header
In between...
  The default content
© 2013

Can be extended in this way:

Hello world!
    My own header

And the result is:

Hello world!
This a template to extend
  My own header
In between...
  The default content
© 2013

CDI support

Contexts and Dependency Injection for the Java EE platform is a great programming model. Named CDI beans are automatically accessible via Unified EL and thus available on JSP/JSF pages. Trimou built-in CDI extension allows you to do the same. It automatically registers a special resolver which is able to lookup a named bean.

Suppose we have the following bean:

public class DataProvider {
    public String[] getData() {
        return new String[] {"foo","bar"};

We can automatically use it in our template:


to render something like:


CDI extension also implements a custom scope which is active during each rendering of a template (there is exactly one bean instance per template rendering). This could be useful in Java SE where usually only @ApplicationScoped and @Dependent built-in scopes are available. You can annotate your bean with org.trimou.cdi.context.RenderingScoped to declare the rendering scope.

PrettyTime - a nice way of displaying date and time

Most applications do have to display the date and time correctly. There's a lot of stuff in Java to handle dates properly. But sometimes it's useful to render nice relative timestamps like "right now" and "10 minutes from now". This is why Trimou integrates PrettyTime.

MustacheEngine engine = MustacheEngineBuilder.newBuilder().build();
// The PrettyTimeResolver is automatically loaded if you place the extension jar on the classpath
Mustache mustache = engine.compileMustache("prettyTime","{{now.prettyTime}}");
String output = mustache.render(ImmutableMap.<String, Object> of("now", new Date()));
// Renders something similar:
// moments from now

Minify your templates

It's very common to minify JavaScript/CSS files so why not the template itself? You can save some bandwidth and also increase the performance of the rendering a little bit. Trimou integrates small and efficient HtmlCompressor library. There are two ways to minify the templates.

It’s possible to register a special listener to minify templates before parsing/compilation:

MustacheEngine engine = MustacheEngineBuilder.newBuilder().addMustacheListener(Minify.htmlListener()).build();
Mustache mustache = engine.compileMustache("minify_html","<html><body>     <!-- My comment -->{{foo}}  </body></html>");
String output = mustache.render(ImmutableMap.<String, Object> of("foo", "FOO"));
// Renders:
// <html><body> FOO </body></html>

Or use a special lambda to minify some parts of the template contents:

MustacheEngine engine = MustacheEngineBuilder.newBuilder().build();
Mustache mustache = engine.compileMustache("minify_html_lambda","<html><body><!-- Remains -->{{#mini}}<!-- Will be removed -->   FOO {{/mini}}</body></html>");
String output = mustache.render(ImmutableMap.<String, Object> of("mini", Minify.htmlLambda()));
// Renders:
// <html><body><!-- Remains --> FOO </body></html>

Eventually you can also implement your own minifier and leverage the existing infrastructure.

Microservices for Java, explained. Revitalize your legacy systems (and your career) with Reactive Microservices Architecture, a free O'Reilly book. Brought to you in partnership with Lightbend.


Opinions expressed by DZone contributors are their own.


Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}