Trim Your Mustache Templates!

Trimou is a Mustache templating engine implementation written in Java. Since version 1.5 a helpers API inspired by Handlebars.js is also included. The goal is to provide a simple to use and easy to extend templating engine for any Java SE or Java EE application. Trimou is available under the Apache License 2.0.

The most notable advanced features include:

  • Template caching
  • Template inheritance
  • Helpers API (inspired by Handlebars.js)
  • Many extension points (template locators, resolvers, text support, etc.)
  • Ready-to-use extensions out of the box (CDI, Servlets, PrettyTime, Dropwizard, etc.)

Get started

All the artifacts are available in the Maven Central Repository.

<dependency>
  <groupId>org.trimou</groupId>
  <artifactId>trimou-core</artifactId>
  <version>1.7.3.Final</version>
</dependency>

And now for something completely different...

System.out.println(
    MustacheEngineBuilder
        .newBuilder()
        .build()
        .compileMustache("hello", "Hello {{this}}!")
        .render("world")
);

Template locators automatically locate the template contents for the given template id. So it’s not necessary to supply the template contents every time the template is compiled. Moreover if the template cache is enabled (it is by default) the compiled template is automatically put in the cache and no compilation happens the next time the template is requested.

The usual workflow looks like this:

  1. Build the engine and add template locators as needed
  2. Store the reference to the MustacheEngine
  3. Whenever the template is needed, obtain the reference from the engine

    MustacheEngine engine = MustacheEngineBuilder
        .newBuilder()
        .addTemplateLocator(new FilesystemTemplateLocator(1, "/home/trimou/resources", "txt"))
        .build();
    Mustache mustache = engine.getMustache("foo");
    String output = mustache.render(null);

This useful feature is not supported in the spec. Trimou basically follows the way mustache.java implements the template inheritance.

  • In the extended template (parent), the sections to extend are defined - use $ to identify such sections.
  • A section identified with < includes the extended template
  • In the extending template (child), the extending sections are defined - again, use $ to identify such sections. Sections to extend may define the default content.

The following template with name "super":

{{$header}}
  The default header
{{/header}}
In between...
{{$content}}
  The default content
{{/content}}

Can be extended in this way:

Hello world!
{{<super}}
  {{$header}}
    My own header
  {{/header}}
  Only extending sections are considered...
{{/super}}
Lalala...

And the result is:

Hello world!
    My own header
In between...
  The default content
Lalala...

Helpers are de-facto tags which are able to consume multiple parameters and optional hash map. There are some built-in helpers registered automatically (if, unless, each, etc.). Trimou also provides some useful helpers which are not registered automatically, e.g. ResourceBundleHelper.

Suppose we have the following resource bundle file:

my.message.key=My name is %s!
hello.key.messageformat=Hello {0}!

We can use the ResourceBundleHelper to render messages. First register the helper:

MustacheEngine engine = MustacheEngineBuilder
    .newBuilder()
    .registerHelper("msg", new ResourceBundleHelper("messages"))
    .build();

Now let's create the template:

{{msg "my.message.key" "Martin"}}
{{msg "hello.key.messageformat" "world" format="message"}}

And the output is:

My name is Martin!
Hello world!

Feel free to create your own helper!