Building the ideal web application template engine

A month and a half ago I had put out a call for what I was calling the ‘ideal web application template engine‘ along with a list of requirements that I thought would be present in such a system.  Since then I looked a bunch of them and decided that I like the simple markup that mustache defined but none of the implementations were up to doing what I wanted.  This led me to embark on building a new engine with for that markup for my chosen platform, Java, which I called creatively, mustache.java.  Though it claims to be ‘logic-less’ I would say that it has some amount of logic. It will loop over a set of objects and it will check booleans, but I think it is about as close to logic-less as you would want to be in a template language.  So, let’s look at each of the requirements and how I ended up implementing them:

  • Works well with HTML5/CSS3 progressive enhancement

This one is straight-forward.  Because I put no limitations on the generated text you can actually generate almost anything with mustach.java, in fact, I am using it in another project to generate Java source for Avro objects.  It is really overkill for that project but it is so easy to use that I used it anyway.

  • Allows mock data within the template that is replaced at runtime
  • Client-side version that leverages the mock data for shift-reload debugging

These I implemented somewhat differently from the requirement because the mustache template language is not tag based.  I have actually thought about whether it might make sense to make it tag-based and get the full requirement, but I digress.  What I did get to is a system that is easy for a frontend developer or designer to use without having the whole system running on their machine.  Included with mustache.java is a mini-server (called handlebar, thanks for the name Luke) that combines mock json data with mustache.java templates. This lets them view a fully rendered version of the page they are working on with the required templating information that will be used in production but without running a big production system. In fact, because mustache.java dynamically generates and compiles Java code, they can fire up handlebar in directory along with their mock data and just keep reloading the page to see the effect of changes they make.

  • Composable components, not monolithic pages
  • Very little or no business logic in the templates

The choice of mustache as a base template language ensured that this would be the case.  Including a partial within a template is easy and makes pages very easy to compose. I still miss the Django template style extends/block system and may extend mustache to support it. Having to remember to include things like the header and footer on every page doesn’t seem necessary.  As I said above, I think that mustache has the minimum reasonable logic.

  • Concurrent evaluation possible

This one was very important to me from a performance perspective. My implementation makes every effort to be as low latency as possible for the end user.  At every possible point in template evaluation things are actually executed in separate threads or purely asynchronously in the case of external I/O like HTTP requests to other services.  The one last thing I am going to do here is to allow not only a straight-line evaluation of the template but the possibility of specifying a timeout so that you can return different markup if evaluation doesn’t return in time. It may be unnecessary to have this in the base template engine though, still looking at the design of the feature.

So how easy is using the template system?  I think I can answer that question by looking at the relevant portions of the implementation of handlebar:

final MustacheCompiler mc = new MustacheCompiler(new File("."));
....
Mustache mustache = mc.compile(new BufferedReader(new FileReader(filename)));
FutureWriter fw = new FutureWriter(res.getWriter());
File file = new File(mocks, base + ".json");
if (file.exists()) {
  BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
  JsonParser parser = jf.createJsonParser(bis);
  JsonNode json = parser.readValueAsTree();
  mustache.execute(fw, new Scope(json));
} else {
  mustache.execute(fw, new Scope());
}
fw.flush();

The most interesting part of this is the FutureWriter. The future writer lets mustache write evaluated templates completed out of order in template order. The scope is essentially a sophisticated context object that knows how to pull data from Java objects of various types, including raw object fields and methods, Maps and Json objects. Conveniently, you can also store values in it directly. There are some things I would like to extend at some point, however, for all practical purposes the template system is finished.

This entry was posted in Java, Technology. Bookmark the permalink.
  • Blah

    StringTemplate

  • http://www.javarants.com spullara

    I took a look at it. The engine itself doesn't have the functionality I needed and I would have had to rewrite that part anyway but it is a reasonable language.

  • Koalillo

    Please, please, please, make it so:

    * templates do not need to be stored on the filesystem
    * template inclusion is as nice as JSP's tag fragments.

  • http://www.javarants.com spullara

    1. How would you like to reference them? Classloader? URL?
    2. The problem with this is that logic gets into your templates. Right now all the metadata that would normally be included with your tag in this framework is in the code that supports the template, not hardcoded into the template itself.

  • Koalillo

    1. I'd say provide a template lookup interface, handle them just like you do know (i.e. public interface TemplateLookupEngine { public InputStream getTemplate(String name); } or something like that).

    2. OK, after re-reading partials I kinda get the idea…

    The thing about most template engines I find is that they are either completely tied to the filesystem or that their mechanism for not being tied to the fs is an afterthought. I want my CMS to store templates in the same backend where I store content, with the same properties (i.e. JCR with versioning and branching, etc.).

    The other thing is that template inclusion is one of the most important features in a template engine…

  • Sproket

    If you want true logic-less then look at:

    http://jolene.sourceforge.net

    I don't really bother maintaining it since it works for 99% of my cases. Jolene just reads HTML and stores the DOM as simple JavaScript styled object. It's a true separation of concerns.

  • http://www.javarants.com spullara

    1. That seems very reasonable. I was actually planning on doing something like this anyway, thanks for the reminder.
    2. Yeah, jsp tag-like behavior should work but the implementation is separated out from the template.

    BTW, it is an open source project and I welcome changes like #1.

  • http://www.javarants.com spullara

    Just realized you can already do this in mustache.java. You can pass in your own superclass for generated Mustache classes and override the partial() resolution method.

  • Koalillo

    Cool! That's a very important feature for me!

  • Ggg

    come on guys!nwe need logic everywhere… how could we chose less-logic stuff…. are we moron?

  • http://jetwick.com/ Peter

    The problem with templating is that a new developer is required to learn it and it is another lib which could have bugs. Another big problem is the ‘partial’ thing which was really really annoying for me the last time I did RoR. So, I think “Composable components, not monolithic pages” is very hard to achieve with them …

    There are 3 template-less solutions in the Java world I am aware of:
    Apache wicket where you code with Java and html,

    vaadin (via gwt) where you code in pure Java,

    and an agpl project itsnat (through its license I don’t know much of it)

  • http://twitter.com/jawher Jawher Moussa

    Hi there,

    I’m a bit late to the party I know.

    I too am very interested in templating in general, and wasn’t very happy with the existing solutions out there. I found Mustache to be a bit better than the rest. I’ve layed out my ()detailed opinions in a blog post over here: http://jawher.wordpress.com/2011/01/06/on-templating-and-a-shameless-plug-of-moulder/

    I’ve also went the extra mile and created a templating library that isn’t just JSP with nicer tag names which I called Moulder and made it available under the MIT license in Github: https://github.com/jawher/moulder-j

    Here’s another post that shows Moulder in action: http://jawher.wordpress.com/2011/03/03/moulder-in-action/

    Sorry for the multitude of links: I’m not just trying to spam your blog, but I’d be very interested in what you think about Moulder’s approach.

    Cheers !

  • Pingback: New features and extensions in Mustache.java | java rants

  • Anonymous

    Shameless plug to my own library: http://code.google.com/p/jatl/ Which is template-less in perhaps a different way then you mean :)

  • http://twitter.com/greenlaw110 Green Luo

    May I introduce my work Rythm: a high performance template engine using Razor like syntax. It’s very clean and easy to use. It’s 2 to 3 times faster than velocity. Have a look at http://rythmengine.com/

  • Tom McClure

    My java template engine, Chunk, is similarly logic-averse. It can do loops and simple if-else blocks but really tries to be just a mature tag-based template engine. Templates can come from filesystem, or a jar, or a cms/db. It has a great system for including other templates (and a framework for referencing one template from another), either straight-up:

    {^include name_of_template}

    or with prepared parameters

    {^exec TEMPLATE}…{/exec}

    Lots of built-in tag-filtering a la {~tag|trim} and you can write your own filters.

    More info here:
    http://code.google.com/p/chunk-templates/

    Full docs here:
    http://www.x5software.com/chunk/wiki/

  • http://twitter.com/mitc0185 Erik Mitchell

    Very interested in the handlebar portion. We implemented a very similar system at my last job, except we were using Freemarker. It was incredibly effective.

  • http://twitter.com/sampullara Sam Pullara
  • Eric S

    What functionality is that, exactly? (I ask this as someone who’s arrived here via Google, researching “pure” templating languages, and who has been looking at ST, and came across a link about Mustache/java. This is one of the only hits I’ve found saying something in comparison of the two.)