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:
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.
Comments for this entry are closed. If you'd like to share your thoughts on this entry with me, please contact me directly.
Nevow Stan can’t be simply defined as “directly generating HTML output from Python code”, you have to closely look at how the Nevow rendering process actually happens.
The argument of needing to know the back end code is pointless, in many cases it could be the inverse - the template designer could specify where items should be placed by the renderer that the programmer writes. With template languages like Django and Smarty (or whatever else) you’re implicitly demanding that control logic exist in the template, not slots for a renderer to replace (ie, patterns vs blatant for-loop structures).
The key argument for XHTML templates is that they can in fact be parsed by any XHTML compliant parser ad hoc before they are rendered. Thus your “webby” could modify them in Dreamweaver etc without having a broken model to guess around where things might land up.
You also missed the point of my definition of a template. A single template should be generalized as far as possible to be able to exist between many other pages, and not have a single template for each page function. Using a combination of the “Stan idea” and a pure XHTML template - a base class can be generalized to provide a single template that can cover a whole site using CSS and JS etc to achieve a pure separation. Nevow Fragments is also a nice idea which allows you to further sub generalize templates into fragments to provide further separation.
Like I said, I still stand by the fact that this is not to say “Everyone should go use Nevow”, I’m only saying that it provides better separation ideas than any of the other frameworks I’ve seen and worked with.
I dunno, the doc there seemed pretty clear that the DIV would be replaced with the output of the Python method it called. Which seems to mean that the XHTML output needs to be generated by the Python method.
Well, we (Django) are saying two pieces of control logic should be present:
ifandfor. And you still don’t seem to have gotten the hang of presentational versus application logic — why shouldn’t the template author be able to say things like “for each article in the list of latest articles, output an H3 containing the title, and a P containing the excerpt”? That’s presentation. Hence it belongs in the presentation layer.Setting aside what a derogative way of looking at designers that is, your “webby” is going to have to be mocking things up well in advance of whenever the backend is ready to develop live templates. So, as designers have done for half a millennium or so, the aforementioned “webby” can use good old Lorem Ipsum to fill in the holes. When the content is ready to hook up to, yank the greek text and replace with the correct template triggers.
Template inheritance. Template blocks. Django’s got ‘em. What’s your argument again?
And I’m only saying that there is such a thing as presentational logic, and that it belongs wherever the presentation is defined. Which is to say, in the template.
As a designer, I think I’d be insulted if I was told that I couldn’t possibly understand the complexities of an if statement or a for loop.
Nevow’s syntax, to me, is more complex to understand in comparison to Django template syntax.
Speaking with no knowledge of Django, I imagine that for/if structures could be eliminated or reduced through the use of template blocks, if that were so desired. In that a designer could create a template block for the ‘if’ and then another block for the ‘else’ and the programmer could include the logic at the application level.
Presentation logic is still application logic but I understand the desire to pull minor control structures into the template so as to avoid more mundane template decisions from creeping into the application. It doesn’t have to be all or nothing.