The perfect template engine

There are a ton of template engines out there, for every different language and platform you can imagine. Some people claim PHP is just a fancy template engine. Others say printf is the first and only real template engine. There are many tools out there that meet various niches and requirements in this fairly broad space. Many templating engines are only available for one or two programming languages/platforms. Without debating the merits of the platforms, here are the criteria for the perfect template engine.

Be output format agnostic

Template engines are most commonly used to produce SGML and it’s derivitives, XML and HTML. However, most applications of any substantial size have a need to generate other forms of output, like email messages, or SMS messages, CSS, JavaScript, or (heaven forbid) dynamic SQL. if your template engine is based on XML tags, it makes it kinda hard to generate other kinds of output. So why not use two template engines, one for SGML/XML/HTML and one for other stuff? Genshi is one of the better examples of this approach. They have a single engine that can support two different template syntaxes; one based on XML, one that isn’t. But isn’t it smarter to have a single template syntax that can gracefully handle any kind of output?

Looks

How it looks matters. The templates should be pretty, and the output should be pretty, and the template should look similar to the output. For example, HAML is pretty, and the output is pretty, but the template doesn’t look much like the output. Velocity templates look OK, the output looks similar to the template, but the output is ugly, it’s darn near impossible to have a nicely indented template and nicely indented output.

Speed

The engine has to be fast. It doesn’t make much sense for your application to spend a huge percentage of it’s time rendering a display. That should be the easy part of your application. I know that CPU and RAM are cheaper than they have ever been, and I believe in horizontal scalability, but I also believe in clean, fast code. XSLT is great at a lot of things, but it is _so_ slow.

Code does not belong in templates

We are talking about a template engine, not a compiler. You should not be able to put “code” in your template. This is one of the things I hate about PHP, JSP and ERB. Even though you shouldn’t, you can put any hunk of code you want into your template. PHP is a fairly robust object oriented programming language, but at it’s roots, it was a template tool, and I can put any chunk of code I want into my “template”. If your template language can handle exceptions, or has the notion of subclassing, then it isn’t a template, it’s a programming language.

Logic does belong in templates

There is a place in a template engine for making decisions, just not complicated ones. Looping constructs, conditional statements and variable assignment are all perfectly acceptable things to do in a template. Lots of template engines have this right, with just the right number and function of their template commands. ClearSilver, Velocity and Smarty are good examples of the proper scope of implementation.

Allow definition and calling of macros

I am a firm believer in not repeating myself. The template language should let me define macro’s or snippets or whatever you want to call your reusable hunks of template. The engine should allow for some kind of include directive, so that my commonly used macros can live in a separate file and be accessed from a number of different templates. JSP tag libraries are exactly the right idea, although perhaps carried a bit far.

Can be processed to an intermediate representation for effeciency purposes

We would call this compiling your template, but that would make people think that you can put code in your template. And that is wrong. But there is nothing wrong with making it fast. Cheetah does this, and so does Smarty. Cheetah’s way is better, because processing to an intermediate representation for effeciency purposes (compiling) is a development activity, not a run-time activity. In some languages the interpreter is the compiler (Python and Ruby), but that’s no excuse to do something dumb like compiling at run-time. On a related side note, optimizing runtime performance is a worthwhile and encouraged activity (say what you want about Java, but the HotSpot Virtual Machine is dang cool), and yes, I’m aware that these are essentially the same activities.

Support layouts

And don’t be backwards. Include != layout. Rails has a very nice layout facility. It essentially let you “include” the changing content, instead of “including” the static content. The genshi method works, but isn’t quite as elegant; XML is too verbose to really be elegant.