The Personal Blog of Todd Sharp

Spark Java Views With Apache FreeMarker

Posted By: Todd Sharp on 4/7/2017 11:05 UTC
Tagged: Apache FreeMarker, Groovy, Java, Spark Java
In the last few posts I took a look at using Thymeleaf for view rendering and templating with Spark Java.  Thymeleaf has it's advantages and disadvantages, but I could see using it in an application without suffering too much grief and having it actually be enjoyable to work with.  I thought I'd take a look at another option for views in Spark Java:  Apache FreeMarker. FreeMarker has been around a looooongggg time - since 1999.  Amazingly, it's still under active development (the most recent release was 3/25/17).  Needless to say - it's not legacy, it's aged like a fine wine.

So can it handle view rendering and templating as well as Thymeleaf?  Let's give it a shot.  As with everything, we need to declare our dependency (no, we're not still talking about wine here):

compile group: 'com.sparkjava', name: 'spark-template-freemarker', version: '2.5.5'

Next we'll add a new route in the Broadcast class just as before:

Our view files with FreeMarker go in src/main/groovy/resources/spark/template/freemarker.  Let's look at a SiteMesh equivalent example since that's what we looked at last with Thymeleaf.  FreeMarker calls their layout templates "macros", so let's create a simple layout template that we'll then apply to our child view.

A few things worth nothing with the macro file above.  Starting with line 1:

<#macro mainLayout title="Freemarker Layout Template" menu="">

The first attribute - mainLayout - is how we'll later refer to this macro from the child view.  The second and third attributes - title and menu - are variables we can pass in from the child.  Title has a default of "Freemarker Layout Template" which will be initialized if nothing is received from the child, and menu has an empty default (it'll be null if empty).

These attributes are now available for our use using the familiar ${} notation.  See line 13, for example, where we use the ${title} attribute and line 42-44 where we loop over the menu List element to create a dynamic menu with a list passed from the model in the child view.  This is the type of functionality that I'd like to see in Thymeleaf - simple passing of model variables from the child to the layout for dynamic bits.  

The last item worth mentioning is on line 53:  the <#nested/> tag.  This will be replaced with the contents from the child caller.  Speaking of children:

Ugh...sorry.  The child template:

The child simply imports and applies the layout - passing variables as needed.  Again, any model values can be rendered using the ${} token format.  And that's it, dynamic content in a reusable format.  It doesn't stop there though - like Thymeleaf there is an entire framework available for use.  Directives, expressions, interpolations - formatting (dates, numbers, booleans, etc), conditionals (if/else, switch/case) - anything you could possibly need inside a view is available.  My only gripe is the lack of IDE support with IntelliJ IDEA Community Edition, but that's yet another reason why I need to shell out for a license.