Templating languages redux
So, I thought I’d explained why templating languages are pretty useful things. Markup is, after all, just about the fastest and simplest way to, well, mark up content for presentation and, when coupled with a small amount of logic, is by far the best way to present the output of a dynamic database-driven web application. I kind of hoped that I wouldn’t have to write more on the topic, because there are so many more interesting things to which I can devote my time.
Sadly, I was mistaken. Enter one Colin Alston. Colin’s idea of a reasoned discussion of the merits of presentational logic in templating languages is to say things like this:
What worries me is that Guido seems to actually approve of this. Most other true Python programmers I know certainly don’t want anything to do with it. I do approve of Python gaining popularity in the world of web applications, I just think that its not entirely useful to have raving lunatics creating crap with it.
And this:
In case any Django developers, or PHP monkeys stumble upon this and don’t comprehend what I’m ranting about, I have a translation: LOLZ NEVOW STAN AND ATHENA ARE PWNZ JOR NOOB FRAMEWORK!
To quote one of my favorite Internet philosophers, I have seen articles of greater erudition float to the top of my Alpha-Bits. Tempting as it is to return the ad hominem, I will confine myself solely to the actual arguments made by young Alston.
He begins by replying to a point made by Adrian, that there is a difference between presentational logic and application logic, and that presentational logic in the presentational layer is and ought to be a perfectly reasonable thing. Alston quips:
That is a good argument, and it works in simple situations. However on large complex applications it means your template code must grow with your application, and it must be maintained by a programmer. That’s not the definition of “template” though.
May I refer the gentleman to a couple of non-programming types who maintain the templates for all of our sites? Granted, Jeff and Wilson have picked up some Python skills in their tenure with Django, but both of them were found to be more than capable of handling Django’s template system at a time when their programming knowledge was non-existent.
This is followed by a dictionary definition of “template” which, being as it is out of the context of web development, is roughly as applicable to the situation as would be a giraffe.
Then we enter into the meat of the argument:
Presentation does not need control logic. Output structures can be generalised semantically enough for CSS and JavaScript to do the jobs that they were invented for. If you have a look at Nevow, it succeeds in doing so, without breaking rules. The problem is that people who work on presentation are generally not programmers - and there is no reason for them to need to know the backend code to recreate how output is formulated.
Again I refer the gentleman to Messrs. Croft and Miner as shining examples of non-programmers who are more than capable of handling templates.
And let us consider how Nevow does things. A glance at the overview informs us that Nevow uses XHTML templates which “contain no programming logic, only nodes tagged with nevow attributes”. A comparison of its own system with Django’s will perhaps illustrate how it does so. If one were to have a function called “foo” which needed to be invoked for output purposes, in Django one would turn it into a template tag which would be called like so:
<div>{% foo %}</div>
Whereas the corresponding Nevow template would look like this:
<div nevow:render="foo" />
You see, Nevow templates work by hanging namespaced attributes on elements in the document (which Nevow’s documentation inistently calls “nodes”) and translating those attributes into Python function calls, and relies on the template author to know the names of the backend Python functions which must be invoked to insert the appropriate content.
Tell me again, what was that about template authors not needing to understand the backend?
Alston moves on:
There is also the question of the computational complexity required in parsing both the code and the template language, and the interactions that take place. Claims have been made for caching of such templates, but this only serves as a byte compiled version which requires less parsing. If you’re building a weblog which spends most of its time in a steady state then that’s all very well, but on a purely dynamic web application - there is little point to template caching so the optimisation is lost.
I wonder at this paragraph’s presence, given that it seems to make no argument whatsoever about the efficacy of templating languages. Also, as an aside, testing has found that Django’s template system is faster when re-loading and re-rendering the template each time than it is serializing and de-serializing rendered templates to and from a cache.
Alston then does a bit more shameless cheerleading for Nevow:
If you look at what is the only real “MVC like” framework, Nevow. You see that caching of the template need not happen - since it is a static entity always, and control code is where it belongs. This doesn’t mean you’re dangerously formulating pure HTML code in your Python code and spewing it back to the web server since Stan binds with the template to generate pure XHTML for you. Your template thus remains a template which can be used in any variation of the code that calls it. Of course Nevow XML templates include markers to let the renderer know where to insert data — however these markers are pure XML, not some concocted template pseudo-language, and they don’t include control structures.
Yes, you’re not “dangerously” formulating HTML in Python. Except, according to Nevow’s template documentation, you are. From the description of the nevow:render
attribute:
Note that the return value of the render method replaces the template node in the DOM, so if you want the template node to remain, you should use ctx.tag.
In other words, the XHTML element which was in the template is completely replaced by the output of a Python method which, one assumes, is expected to be XHTML.
Oh, dear.
This isn’t Nevow propaganda, Nevow has a lot of pitfalls, it’s simply an explanation of a more correct way of doing it.
Pitfalls such as not living up to the claims made for it?
The fact of the matter is, the Django framework seems based around concepts derived purely from PHP way of life (and the template system seems to bear frightening analogues to Smarty). This is certainly not a good path for future web development in demanding, or mission critical applications.
Ah, we have to get that dig in there somewhere. For the non-web-developers in the audience, comparing something to “the PHP way” is what you do when you can’t find a constructive argument against it. It’s somewhat like people who, in the absence of concrete reasoning to support their disagreement with a politician, compare him to Adolf Hitler.
Also, I’ve seen some lovely PHP code in my time. That there is bad PHP out there says little about the language and much about some of the users.
Put another way, I’m a fan of innovation not emulation. Innovation is what grew Ruby On Rails success, it was a truly impressive alternative to ways of building web applications then — but with web 2.0, Ajax and a lot of other good technologies doing the rounds, the old ways of thinking do not apply, or at least are merely a hack rather than an optimal solution.
So… innovate like Rails’ default template system, which embeds Ruby logic in the HTML? It’s all so clear now.
I really sincerely hope this is the last time I have to stand up for Django’s template system, but I have a feeling it won’t be. I’ve come to the conclusion that web developers go through certain phases:
- In the first phase they discover a language like PHP or classic ASP which makes it extremely easy to intersperse program logic amongst HTML.
- In the second phase they have been bitten by the consequences of over-mingling logic and presentation, and violently react by retreating to the opposite extreme.
- In the third phase enlightenment is achieved, and they realize that application logic belongs with the application layer and presentational logic — kept as minimal as possible — belongs with the presentation layer.
I went through those phases myself: when I learned PHP, my first web programming language, I wrote a blog app (though at the time I was unaware of the word “blog” — it hadn’t yet entered into wide enough circulation for someone like me to notice). It was a set of PHP scripts, each of which contained all of its logic and all of its HTML output. It was horrific.
The second iteration of my blog app contained very little visible HTML; there were a few structural tags, mostly DIVs, in each page which contained short inline calls to externally-defined PHP functions, and those functions generated the content of the pages.
The third iteration never deployed because I finally discovered off-the-shelf blogging tools, but involved a templating system very similar to Django’s. The templates were mostly HTML, with a few concise control structures and easy access to drop in variables.
I thought about treating the above as a “levels of knowledge” list in the same vein as others which have been floating around the web-professional blogosphere this past week, but that’s a bit more condescending than even I’m comfortable with. So I’ll just end on that note, and the next time someone rants about templating languages being evil because they contain presentational logic, maybe I’ll refer them back here.