Integrating Joda-Time and Freemarker

One nice aspect of the Freemarker template engine is the way that it intelligently displays typed model data. Dates, for example, are presented in a human-readable format which can be controlled in the view using Freemarker builtins. This works well, and is good for helping view concerns stay in the view code. However, one difficulty with this feature is that Freemarker doesn’t understand all domain types out of the box. joda-time DateTime objects are a good example, and this article shows how to teach Freemarker how to render that type of value.

As part of its template processing model, Freemarker wraps each domain object to be displayed in a concrete derivation of TemplateModel. Template model objects then form the basic value types that the templating engine processes to render a view. It is the template model corresponding to a domain object that controls how that domain object is displayed. Integrating Joda-Time into Freemarker requires extending the object wrapping process to understand Joda-Time objects and wrap them into an appropriate Freemarker template model object.

The object wrapping process is implemented using a concrete instance of the ObjectWrapper class. The default object wrapper class is DefaultObjectWrapper, which can be extended as follows:

package com.ksmpartners.util;

import freemarker.template.DefaultObjectWrapper;
import freemarker.template.SimpleDate;
import freemarker.template.TemplateDateModel;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

import org.joda.time.base.AbstractInstant;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FreemarkerObjectWrapper extends DefaultObjectWrapper
{
    @Override
    public TemplateModel wrap(final Object obj)
        throws TemplateModelException
    {
        if (obj instanceof AbstractInstant)
            return new SimpleDate(((AbstractInstant) obj).toDate(), TemplateDateModel.DATETIME); 

        return super.wrap(obj);
    }
}

Once the class is defined, the next step is to have it noticed by Freemarker. Usually, this is done with the setObjectWrapper method on the Freemarker configuration object. However, In Spring, it’s a little different because Freemarker configuration is specified through the FreeMarkerConfigurer bean definition in the context. The key is to add a setting for object_wrapper, like so:

  <bean id="freemarkerConfig"
        class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
    <property name="freemarkerSettings"> 
      <props> 
        <prop key="object_wrapper">com.ksmpartners.util.FreemarkerObjectWrapper</prop>
...

Once this is done, Freemarker will display Joda-Time instants in the same fashion it does for the Java built-in classes. The Freemarker date built-ins will also work as expected. If you’re interested in controlling the date formats used by the built-ins, they can also be configured in the freemarkerSettings block as a property:

    <property name="freemarkerSettings"> 
      <props> 
        <prop key="object_wrapper">com.ksmpartners.util.FreemarkerObjectWrapper</prop>
        <prop key="datetime_format">yyyy-MM-dd HH:mm</prop>
        <prop key="date_format">yyyy-MM-dd</prop>
        <prop key="time_format">HH:mm</prop>
      </props> 
    </property> 
Categories: Freemarker, Java, Spring
Trackback URL for this post: https://www.ksmpartners.com/2014/10/integrating-joda-time-and-freemarker/trackback/

Leave a Reply

Your email address will not be published. Required fields are marked *