Down with templating languages

Phred on 2007-06-06T21:37:06

Last night I was going to blog about the how the second system is the inherently dangerous, according to Frederick P. Brooks. As I researched it though, I came across Greenspun's Tenth Rule, which was an interesting read. In short, it says that any sufficiently complicated C or Fortran program contains a buggy implementation of Common Lisp.

It's taken me a few hours for this material to coalesce in my brain, but it seems like templating languages suffer from this same fate. I don't want a lot from templating languages. I want to be able to take some data that my application has generated, throw it at a template, and have it do what I expect.

When I started out with Mason many moons ago, it did exactly that. It was friggin' great. But Mason has all these hooks and cool features which can be (and often are) abused by programmers spending lots of time trying to save themselves future work by implementing shortcuts. Eventually, a fair amount of work goes into debugging these shortcuts, and it's evident that any expected economies of scale are falsehoods due to the fact that the maintenance cost for those shortcuts becomes overwhelming. Mason::Strict anyone??

So later on I started using Template Toolkit. I thought "This is great, I can throw objects at templates and it just works." Then I started working with more experienced template toolkit users, who knew it well enough that they were able to use it as a programming language, not just a templating language. Therein lay the danger. I managed to generate all sorts of esoteric runtime errors due to the fact that my macros didn't have the correct syntax, or some other crap that perl usually catches at compile time (and tells me the line number where the error is, instead of the package).

Along the way I used HTML::Template, which was nice also, but it was too strict for my liking. I couldn't throw objects at it, I had to serialize the objects into hashes. And I had to consult the docs to perform rudimentary operations such as loops, which I had committed to memory from perl.

So here I present to you Moyer's Eleventh Rule of Templating Languages. "Any sufficiently complicated templating language contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Perl". Take it for what it is worth, preferably with a large grain of salt. Most templating languages aren't perfect, and neither am I :)


Mixed reactions

merlyn on 2007-06-06T22:52:27

Part of me wants to object, but part of me totally agrees.

This is indeed why I'm pretty vocal against newbies creating their own templating language. They all start out "simple", and then slowly add variables (of course), and then decision and iteration. And once you have state/decision/iteration, you have turing completeness, and you start treating the templating language like a programming language, and it's all downhill from there.

One of the things I like about Template Toolkit though is that it at least gets hard at some point to do programmy sorts of things. That's always my clue that I'm in the wrong layer: move that stuff to model or controller, please!

The Mason users don't get that same sort of warning beep. They can keep dumping more and more embedded Perl code into the templates until it's a nightmare. And believe me, I've seen a couple of huge projects in my career in Mason where a lot of code that was not view related was all buried in the views where the only way to test it was to do webscraping of the result. Ugh.

Re:Mixed reactions

gav on 2007-06-07T00:21:51

Is really using something like TT2 for "programmy" things so wrong?

I have abused TT2 to develop whole websites where there's a simple Apache module that can load the base template and pass it an object which can fetch records out of the database as hashes.

The great thing about this is that people who don't think of themselves as being able to program are doing clever things with loops, and writing conditional logic. Of course you end up with something that might not be as neat as if it used a MVC architecture and "dumb" templates, but the real world isn't neat and I'm more interested in empowering others to get things done.

Paul Graham's ViaWeb (now Yahoo Store) uses templates written in Lisp, that you develop with a web interface which basically hides the parenthesis. I've seen what most people would consider horrible ugly, contorted code, but the ability for a non-programmer to program and get results is something that's always impressed me.

Re:Mixed reactions

sigzero on 2007-06-07T00:52:50

I don't think he was advocating that getting "programmy" with TT is wrong. He does advocate that TT has a ceiling where the "programmy" stuff gets hard and that is his signal to take a step back and look at what he is doing and how he is doing it.

Re:Mixed reactions

perrin on 2007-06-07T19:11:59

Yes, it really is dangerous to write anything significant in the TT language. The problem is, as Fred pointed out, TT's language sucks at error messages and catching mistakes when compared to Perl. Perl gives good diagnostics, has a debugger and profiler, has strict and warnings, has perltidy, etc. TT has none of these things. Perl is also a lot more efficient in most cases.

I think the TT language is great, as long as you stick to using it for templating tasks: put this here, loop through these. Any time I see someone trying to modify the data passed in to the template, or load data from the template, or do any kind of calculation in the template, I recommend that they either put that in the script that calls the template or encapsulate it in an object or plugin.

Re:Mixed reactions

Alias on 2007-06-07T09:00:28

I had a simple templating language for a year or so.

I think when I hit the need for conditionals I realised I was heading for trouble and scrapped it for TT2.

Lately, however, I've been trying desperately to resist writing Template::Tiny (minimalistic version of Template Toolkit) :)

Of course, for the really simple templating language I just use...

$text =~ s/\[\%\s*(\w+)\s*\%\]/$hash{$1}/ foreach 1 .. 10;

or variations :)

that's why I prefer Mason

slanning on 2007-06-07T13:54:21

The reason I generally dislike template systems like Template Toolkit, is that they have their own invented programming language, reimplementing programming constructs that are already implemented by the Perl language. It's kind of like Esperanto (I don't want to start a troll), I just personally feel it's unnatural.

On the other hand, it's important to separate the template from the business logic, and the template often has to be simple enough for non-programmers to use.

So maybe you're right. Let's get rid of templating languages. :) Why are we still writing things at such a low level, anyway? Templates, meh.

You can go this far, but no further...

bart on 2007-06-07T20:33:49

Templates are a nice concept, and I don't mind putting some logic in them, but, not too much.

So, how much is too much? Well, this much: a templating system may embed values of variables, apply filters to them (for example HTML escaping), provide simple conditionals, include other templates. And that's about it.

A templating system should not provide ways to connect to a database or to invoke SQL. Your controlling program should already have taken care of that.

The way I would allow directly fetching data from a database from within a template is by using a tie like mechanism: you treat it like a variable, and the fact that under the hood it fetches the value from a database is not really relevant.

Ain't it nice you can do all that just using plain Perl.

Re:You can go this far, but no further...

chromatic on 2007-07-07T02:27:45

A templating system should not provide ways to connect to a database or to invoke SQL.

That would have fixed PHP, back in the day.

Re:You can go this far, but no further...

Matts on 2007-07-07T02:33:57

No. They would have still provided a broken mail() command.