Skip to main content

Mustaches in the world of Java

Mustache is templating system with implementation in many languages including Java and JavaScript . The templates are also supported by various web frameworks and client side JS libraries.

Mustache has simple idea of "logic-less" system because it lacks any explicit control statements, like if, else or goto and also it does not have for statement however looping and conditional calculation can be achieved using custom tags that work with lists and lambdas.


The name unfortunately has less to do with Tom Selleck but more with the heavy use of curly braces that look like mustache. The similarity is more than comparable.


Mustache has implementation for most of the widely used languages like:  Java, Javascript, Ruby,Net and many more.





The client side template's in JavaScript

Let say that you have some REST service and you have created a book view object that has an additional function that appends amazon associates id to the book url:



var book = {
  id : 12,
  title : "A Game of Thrones",
  url : "http://www.amazon.com/gp/product/0553573403/",
  amazonId : "myAwesomeness",
  associateUrl : function() {
    return this.url + '?tag=' + this.amazonId;
  },
  author : {
    name : 'George R. R. Martin',
    imdbUrl : 'http://www.imdb.com/name/nm0552333/',
    wikiUrl : 'https://en.wikipedia.org/wiki/George_R._R._Martin'
  },
  haveInStock : true,
  similarBooks : [{
    id : 13,
    title : "Decision Points"
  }, {
    id : 13,
    title : "Spoken from the Heart"
  }],
  comments : []
};
 


The standard way of rendering data without using templates would be create an output variable and just append everything inside and at the end just place the data where it should be.

jQuery(document).ready(function() {
  var out = '<div class="book-box"><h3>' + book.title + 
  '</h3><span> is awesome book get it on <a href="' +
 book.associateUrl() + '">Amazon</a></span></div>';
  jQuery('#content-jquery').html(out);
});


This is fairly simple but if you for example want to change the span element with div it takes a little bit of time to figure where it should be closed and often you can miss if the element should be in single quotes or double quotes. The bigger issue here is that the content is peaces of strings that need to be easy to styled via CSS and JavaScript.  As the code gets bigger this becomes unmanageable and changes to anything become slower especially if you add on top of this jQuery's manipulation functions like appendTo() or prependTo(). This direct use of out+= type of creating the content reminds me a lot of HttpServlet style of using  print writer and doing out.print() and for the same reason why this was almost abandoned we should not do this in JavaScript.
To simplify work we can add template engine like Mustache that is one of many client side tempting engines. So how does a template in mustache looks like, well for the example above with the book it would look like :


    <script id="book-template" type="text/x-mustache-template">
      <div class="book-box">
      <h3>{{title}}</h3>
      <span> is awesome book get it on 
        <a href="{{associateUrl}}">Amazon</a>
      </span>
    </div>

So this template can be placed anywhere on the page and then selected and rendered when you need it:

jQuery(document).ready(function() {
  var template = jQuery('#book-template').html();
  var renderedData = Mustache.render(template, book);
  jQuery('#content-mustache').html(renderedData);
});

The render method accepts the content of the template and the view object book, what is great here is that the template looks almost the same as html thus make it easy to style, change and maintain.
Also you can use section like :  {{#conditon}}  code or data here{{/condition}} where  if it  evaluates to true, the section is rendered, otherwise the whole block is ignored.
If the conditions returns nonempty list this can be iterated using the same construct.
Inverted condition is done using  {^conditon}}  code or data here{{/condition}}. 
Dot notation can be used to access subelements (not in every implementation), for example if you wanted to render the authors imdb page from the previous example it would be like {{author.imdbUrl}}.There are structures called partials that can be used if we need render time inclusion of partial elements, also if needed some of the standard behavior of Mustache JS can be overridden.
You can get the example from https://github.com/mitemitreski/blog-examples/tree/master/mustache-js or play around with the following jsfiddle

Server side rendering Mustache in Spring MVC

There is an implementation of Mustache templates for Java called Mustache.java and another one called JMustache . As far as usage in web frameworks  is needed there are few articles out there about using Mustache in Java web applications based on Struts for example but I went with the Spring MVC option since I found it more interesting for my use.
For the example I used the mustache-spring-view  that is fairly simple to add using maven: 
 
    <dependency>
    <groupId>com.github.sps.mustache</groupId>
    <artifactId>mustache-spring-view</artifactId>
    <version>1.0</version>
    </dependency> 
 
This will automatically retrieve jMustache  :

 +- com.github.sps.mustache:mustache-spring-view:jar:1.0:compile
  \- com.samskivert:jmustache:jar:1.2:compile



The next part is including the view in the servlet context and adding the appropriate paths:



<beans:bean id="viewResolver" 
class="org.springframework.web.servlet.view.mustache.MustacheViewResolver">
 <!-- FIXME reload every time-->
 <beans:property name="cache" value="false" />
 <!-- The default view path is below -->
 <beans:property name="prefix" value="/WEB-INF/views/" />
 <!-- The default suffix path is below -->
 <beans:property name="suffix" value=".mustache" />
 <beans:property name="templateLoader">
  <beans:bean
   class="org.springframework.web.servlet.view.mustache.MustacheTemplateLoader" /> 
 </beans:property>
</beans:bean>


As you can see the config is extremely simple you just need to add the path where the templates will be stored the suffix that the templates will end in, the actual template loader and if the templates should be cached. It is very good during development to set this property to true since that way you will get instant update on the changes in your templates.
The controller will be very simple one since this is just a small proof of concept:
 
/**
* Hello Mustache.
*/
@Controller
public class HomeController {

  private static final Logger logger = 
     LoggerFactory.getLogger(HomeController.class);

  /**
  * Simple controller that 
  * redirects to home and adds map and date objects.
  */
  @RequestMapping(value = "/", method = GET)
  public String home(Locale locale, Model model) {

    Date date = new Date();
    DateFormat dateFormat = 
        DateFormat.getDateTimeInstance(DateFormat.LONG,
        DateFormat.LONG, locale);

    Properties properties = System.getProperties();

    Map<String, String> map = 
       new HashMap<String, String>((Map) properties);

    String formattedDate = dateFormat.format(date);
    model.addAttribute("serverTime", formattedDate);
    model.addAttribute("props", map.entrySet());
    return "home";
  }

}
 
The controller just fills the serer system properties and the current time add passes the model to towards the template.  Acorrding to the previous configuration the template name is home.mustache and it is located in /WEB-INF/views/.  
Template is as simple as it gets, the idea here was just to illustrate how java maps can be iterated.
 
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset=utf-8>
<title>Hello Mustache</title>
</head>
<body>
<div id="container">

  <p>Current server time is {{serverTime}}</p>
  <p>All the current system properties</p>
      <ul>
        {{#props}}
         <li>{{key}} = {{value}} </li>
        {{/props}}
      </ul>
</div>
</body>
</html>
 
So how does it work? Well if we take serverTime it can be java property, key or a method which makes it very simple and readable.  The full example can be retrieved from my github page.
It's just the regular maven clean package and run, it's tested on tomcat 6 with Java 1.6 but it simple enough to work anywhere. While I can't yet say that I have used the servers side rendering in a production environment they most definitely look promising. There are plugins for vim, emacs and textmate but there is no plugin for eclipse. On eclipse you can do a workaround Eclipse->Preferences->General->Content_Types add the *.mustache to be recognized as html, at least you will get the html syntax highlighting.
The cool thing with Mustache is that you can very easily switch whether you gonna use server side rendering on client side additionally it makes it very hard to add unnecessary logic in the templates that makes development simpler.
Don't  forget your app is only hot if it has awesome mustaches.

mustache js
Update
I got few questions regarding the use of partials with the Spring resolver. So here is the clarification. When using partials you need to use the full relative name:

{{> /WEB-INF/views/partial.mustache}}

The updated example can be found on
https://github.com/mitemitreski/blog-examples/tree/master/mustache-java/mustache-spring-mvc that demonstrates the use of partials.

There is a pull request that improves the syntax a little bit on
https://github.com/sps/mustache-spring-view/pull/3 but it is not yet accepted.

Other links



Popular posts from this blog

HTML 5 data-* attributes, how to use them and why

It is always tempting to add custom attributes in HTML so that you can use the data stored there to do X. But if you do that there is no way of knowing if your HTML attribute will not be overridden in the future and used for something else and additionally you will not be writing valid HTML markup that can pass HTML 5 validator and with that you can create some very bad side effects. That is why there is a spec in HTML 5 called custom data attributes that enable number of useful features.

You may go around and read the specs, but the basic idea is very simple, you can add any attribute that starts with "data-" and that attribute will be treated as non-visible data for that attribute. By non-visible I mean that it is not something that gets rendered to the client so it does not affect the layout or style of the page, but it is there in the HTML so in no way this is private.
So let's get right into it, the following snippet is a valid HTML5 markup

<div id="aweso…

Basic Authentication with RestTemplate

Spring Rest Templates are very good way of writing REST clients. By default they work with basic HTTP so if we need to use Basic Authorization we would need to init the rest template with custom HttpClient. This way the Rest Template will automatically use Basic Auth and append to the HTTP headers "Authorization: Basic BASE64ENCODED_USER_PASS".

HttpClient client = new HttpClient(); UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("USERNAME","PASS"); client.getState().setCredentials( new AuthScope("www.example.com", 9090, AuthScope.ANY_REALM), credentials); CommonsClientHttpRequestFactory commons = new CommonsClientHttpRequestFactory(client); RestTemplate template = new RestTemplate(commons); SomeObject result = template.getForObject( "http://www.example.com:9090/",SomeObject.class );

In EE application this would probably be managed by DI framework like Spring Core and only initialized once sin…

Temporary files and directories in Java 7 and before

Sometimes we want to create a temporary file, whether to save some data that gets written by some other application or just to temporary store stuff. Well, usually applications have their own temporary folder where they do this and it gets somehow configured. But why not use the underlying OS specific file like "/tmp/" in Linux so there must be some system property that has this info and there is. The key is "java.io.tmpdir" resulting in "/tmp" in my case or by code:
String tempDir = System.getProperty("java.io.tmpdir"); We can use tempDir  folder as a temporary place to store files, but there are a lot nicer ways to work with files like this even in JDK6 not just in JDK7:
import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; public class TempFile { public static void main(String[] args) { try { // create a temp file File tempFile = File.createTempFile("old-file",…