Templates: Good or Evil?

This cry and whine that draconian handling will break your page and make your users suffer for you if you have a single error is just another legacy of HTML we’ve gotten used to: our toolchains tend to be of the “glue strings together” (aka templates) variety. ... There should never be any part of your publishing toolchain just gluing strings together. Ever.

Source: Aristotle Pagaltzis in a comment on "The Future: HTML or XHTML"

There’s no rule that says templates must only be used to generate HTML. Indeed, many of the RSS and Atom feeds in the wild are generated from some form of template. They are never automatically-generated-behind-the-scenes using language bindings and are very rarely generated using some kind of DOM/SAX API.

Source: Web Services Infrastructure: Kid Templating

I've been meaning to write about this for some time now, though I've never had my thoughts together to any degree to mount a decent case for either side. Problem is, I haven't gotten much closer now, but I figured I'd at least post a few thoughts and conjure up a vague sketch of the issue.

You see, I think it all goes back to thoughts about which I posted almost three years ago. On the one hand, producing something like XML using "proper" DOM invocations and handwavings seems like the "correct" thing to do. Yet, on the other hand, using a templating system lets me get down to business much more quickly and with much more clarity and succinct code.

Yeah, templates provide a range of flexibility sufficient to aim the barrel at your own toes, while an API like the XML DOM keeps everything on the rails--but sometimes you know where you're going and don't need the rails to get you there. Furthermore, isn't it possible to make a template system that Does The Right Thing?

Anyway, it's rather apparent that I'm solidly in favor of templates: After all, a book of mine just hit the shelves which is just rife with template-based generation of RSS and Atom feeds.

My only issue, really, is that I feel vaguely guilty about it.

Archived Comments

  • Ruby has the nice Builder module for this (http://builder.rubyforge.org/). Ruby on Rails uses it for it's rxml templates. So, you still get the speed of templates, but you don't have to worry about those pesky xml rules. Here's a sample Atom 1.0 template used by Typo, a rails weblogging system: http://typo.leetsoft.com/trac/file/trunk/app/views/xml/atom10_feed.rxml
  • Using the DOM to build documents is awfully awkward. Don’t do that. Check Henri Sivonen’s suggestions just published in his HOWTO Avoid Being Called a Bozo When Producing XML. Instead of building a DOM, generate SAX events, using the program structure to ensure proper nesting – or instead of generating the SAX events all manually, generate them by parsing a static XML document and using certain interesting points in the stream (such as Processing Instructions) as hooks for inserting payload. The emission of synthesised SAX events can be generalised by writing a datastructure-to-SAX serialiser, so that you can build your data within your language’s native datastructures prior to outputting it, for maximum comfort. (Of course you serialise piecemeal too, f.ex. by outputting the head of a feed manually, then for each item, building the data structure and immediately serialising it, then emitting the final events to complete the document.) Depending on the complexity of the output, you could directly emit the otuput format or feed the events into to an XSLT transform that generates the full-blown thing from an easy to generate document structure. In both cases this can be done with or without the involvement of a serialiser as middle man. There are plenty of ways to make sure that the entire toolchain from one end to the other consists only of steps that conserve well-formedness, and they need not be any less convenient than using templates.
  • or instead of generating the SAX events all manually, generate them by parsing a static XML document and using certain interesting points in the stream (such as Processing Instructions) as hooks for inserting payload.

    Aristotle: Now here's where I think certain templating technologies get interesting, and may Do the Right Thing. My so-far-favorite templating kit, ZPT, wants well-formed XML as templates--although I think that restriction is unfortunately relaxed as a nod to HTML. On the other hand, my possibly-new-favorite templating kit, Kid, demands well-formed XML as templates. In case you haven't played with them, these two template languages center around the idea that certain attributes on elements define where content provided in a data structure should be inserted / swapped in by the template engine. The engine handles character encodings and such to ensure that the well-formed template results in a well-formed document. Does this match up with what you say up there?

  • I guess the other thing that bugs me about constructing documents via DOM or via generating SAX events—which I'd first discovered in this XML.com article by Uche Ogbuji—is how awkward and removed it is from the view-source XML I've gotten used to hacking around with. Of course, my distaste for programmatically generating things like this goes back to CGI.pm in my perl-hacking days. When I start writing code to generate data that could be mostly done with a template, it strikes me as tangling Model/View/Controller elements and introducing weird context shifts. (ie. h1() vs <h1 />) Not sure if that made sense...
  • Yeah, I was gonna say, Builder for Ruby solves most of the issues with using templates and xml. For RSS and Atom, there's also my Ruby FeedTools library, which makes it even more rediculously easy to get a valid feed up and running. I'm also very tempted to play around with Kid and see how I like it, and perhaps port it to Ruby. From what I've seen so far, it looks like perhaps the nicest templating system yet.
  • It does. I confess I actually kind of liked CGI.pm – because nesting is automatically taken care of without so much typing of end tags, and you can seamlessly weave maps into the code for output loops. I have to note though that I used it as a sort of template language in its own right – I never littered prints all over my code, I kept all the calls in a single place, in fact, usually a single expression. That is also why I find it strange that people create template languages for PHP, which was itself born as a template language. What matters is that the output generation is separate from the processing logic, whether or not the template and the code are in different languages. Anyway, I digress. What I wanted to say is, no, I hadn’t seen either ZPT or Kid. I had put off reading the lesscode.org article you quoted and went back to it after responding here. Now that I’ve read it, I admit I’m intrigued. I’ll have to look into Kid; it sounds like an interesting take.
  • What matters is that the output generation is separate from the processing logic, whether or not the template and the code are in different languages.

    Ah hah, yeah, that's what I was fumbling toward with the sleepy tail-end of my comment. Logic and presentation in separate blocks / files / etc. And then, my take is that if you're going to have your presentation/view separate from the logic/controller, you may as well code the presentation in a form as close to the goal as possible (ie. in XML or HTML, not in s-expressions or the logic implementation idiom)—especially since oftimes you've got separate people or teams working primarily on each. I suspect, however, that a templating system like Kid goes quite a ways toward solving the problem of "gluing strings together". I almost wish it had been further along / I'd been more aware of it before I'd reinvented my own wheels for my book using Python string templates and funky map classes.

  • I suspect, however, that a templating system like Kid goes quite a ways toward solving the problem of “gluing strings together”.

    That's the idea. The correctness of DOM/SAX based contruction with the ease-of-use of templating. The future of Kid is somewhat uncertain. I'm hoping to wrap up 1.0 and stabalize it for Kevin and TurboGears but what I'd personally really love to see is the general concept of "structured templating" reach a wider audience.

  • Oops. Sorry about the rough formatting. For some reason I thought comments were in markdown. Edit away, Leslie.
  • Ryan: Grr. Funny you should mention that—I thought comments around here allowed markdown, too. I think I need to fix that *and* display some copy explaining markdown availablility, since I think that was something about which Aristotle expressed some confusion/surprise before as well.
  • if you’re going to have your presentation/view separate from the logic/controller, you may as well code the presentation in a form as close to the goal as possible

    Oh, I don’t disagree at all. I have been annoyed at the state of XML generation at large, myself. Kid looks very nice, except I have no use for it, being that I’m still a Perlista. (Python just doesn’t feel right to me – like wearing a badly fitting tuxedo.) I’m wondering how much work it would be to port it or a close copy to Perl…

    I think that was something about which Aristotle expressed some confusion/surprise before as well.

    Heh, yeah. Your MT installation permitted Markdown but no literal tags, which caught me off guard once or twice until I noticed. But thankfully it had a preview button, so I could figure it out. I hate how WordPress does not ship with preview button available and enabled by default, and the default configuration doesn't even mention the expected formatting anywhere either. I just suspected that your WordPress was vanilla and used HTML on that hunch – and it worked. Phew. Maybe you can install the gagdget that Ryan uses on lesscode.org? I love that.

  • I just suspected that your WordPress was vanilla and used HTML on that hunch – and it worked. Phew. Maybe you can install the gagdget that Ryan uses on lesscode.org? I love that.

    Your wish is my command. At least, in this instance. I pawed through Ryan's HTML source and got sufficient clues to install this thing and shamelessly steal a snippet or two. Let's see if this preview works and if it accurately reflects what this will look like when I post...

  • I maintain Oddmuse, a wiki engine written in Perl, using CGI.pm to generate the HTML. Often people want me to switch to templates. At the moment, when you want to radically change the HTML for the stuff that is not the wiki content, ie. headers and footers, you need to override the Perl subs that I provide. Somehow that strikes me as natural and easy, but many of my users seem to disagree, preferring to learn a templating system instead of learning to write Perl code. I'm still undecided about the issue. At the moment I'm still sticking to the "write Perl code instead of templating" because being able to write Perl code will make so many other task easy.

  • Alex: Well, from my perspective, I've worked on a lot of teams where you've essentially got two roles—software engineer (SE) and interface engineer (IE). Depending on the company and the team, the SE might understand Perl/Python/Java/SQL while the IE might understand HTML/CSS/Javascript/Flash. There's usually overlap, of course, but these are the roles on paper at least.

    When you're trying to come up with an overarching framework which accomodates collaboration between these two sorts of people and their respective skill sets, it helps to have a bridge between the logic and the presentation which can keep the Perl out of the HTML and the HTML out of the Perl.

    On the other hand... A project like Oddmuse likely has an entirely different user and developer base than the projects I work on at my day job :)

Let there be no Serenity 1701B  Previous Battlestar Galactica's opening teaser Next