I've been writing a fairly simple web app with Scala and Spring that will be running on Google's App Engine. I've been trying to decide which template language (or even languages) to write my views in. I'll be rendering a lot of non-HTML and non-XML and over the years I've noticed some template engines are better at this than others. Also, I'm looking for first class Scala support (so anything you can do with a Java Bean you can do with a Scala object) - ideally built in and at worst trivial to add. Here's what I've come across so far:
I like Google's Closure Template, but there's no "out of the box" support for it in Spring. If I can't find another template engine I like then I will come back and look at how to add some support.
I will start at the point where my experiments ended - apparently FreeMarker doesn't currently work on GAE, as FreeMarker uses some swing classes that aren't available in GAE. This is a show stopper. I didn't run in to this during my experiments as it was working on the local dev server and I wasn't aware of this problem until I was submitting a bug for another problem I found.
During my experiments, I found several other issues, one of which calls into question using FreeMarker with Spring and Java, let alone Scala.
First, there isn't built in object wrapping for Scala objects. By default, FreeMarker will treat Scala objects as Java objects, but as plain Scala objects don't follow JavaBeans conventions access to getters ceases to be trivial. I was able to whip up a Scala specific FreeMarker Model and ObjectWrapper with relative ease, but then I ran into another problem - there doesn't appear to be an easy way in Spring to configure FreeMarker with an alternative ObjectWrapper.
The answer was to create a subclass of org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer and modifying one of the Configuration related methods to return a Configuration with an ObjectWrapper property set to my Scala specific ObjectWrapper. However, I then ran into a problem that I eventually traced to what appears to be a bug in FreeMarker. When Spring sends a model to FreeMarker it uses FreeMarker's AllHttpScopesHashModel - unfortunately AllHttpScopesHashModel's constructor doesn't let it's super class know about the ObjectWrapper that was passed in (it just stores it in a final variable that is private to AllHttpScopesHashModel). This means inherited methods fall back to using Fremarker's default ObjectWrapper - so Scala objects don't work. While working with the FreeMarker source code to make sure this is what was going wrong (it was), I ran into two more issues with FreeMarker.
As I was using the trunk from FreeMarker's SVN repository I assume I was using what will be the 2.4 release of FreeMarker. The first problem I ran into with this was that Spring's FreeMarkerView imports freemarker.core.ParseException, unfortunately ParseException has been moved to freemarker.core.parser.ParseException which obviously breaks Spring 3. As I said above, I have doubts about about using FreeMarker with Spring and any language - this is the reason why. At some point this backwards incompatible API change is going cause someone, somewhere a lot of pain and I don't want to be that person.
While mucking about with FreeMarker's source, I ran into another problem. FreeMarker 2.4 will have some new security features which seemed to cause no end of trouble with GAE. While you should be able turn these features off in the Configuration object, setting the secure property to false had no impact on getting FreeMarker to work with GAE. While I had pretty much given up on FreeMarker by this point, I still wanted to make sure that the reason why my ObjectWrapper wasn't working was because of AllHttpScopesHashModel's constructor so I commented out some security related lines in FreeMarker and eventually got it all working.
I won't be using FreeMarker. There are still a few more template engines to look at before I'll fall back to forcing Closure Templates to work with Spring (I would be astounded if it doesn't work GAE). So, I'll carry on my search (Velocity is probably next).