HTML Templating (Was Re: [ANN] HTMLTemplate 1.0.0)

has has.temp2 at virgin.net
Fri Jun 11 11:39:58 CEST 2004


Chris Green <cmg at dok.org> wrote in message news:<m24qpk65y1.fsf_-_ at catbert.dok.org>...
> David Fraser <davidf at sjsoft.com> writes:
> 
> > It looks cool because it doesn't embed Python code in the template.
> > Do any of the other frameworks have this approach?
> 
> My favorite right now seems to be clearsilver (www.clearsilver.net).

The key word here would be 'code', not 'Python'. ClearSilver does
embed code in its templates, so doesn't count here. (Sorry.:) Ditto
for PSP, TAL, Cheetah, EmPy, htmltmpl and various others I can't mind
offhand. To answer the OP's question, PyMeld, HTMLTemplate and
Nevow.Renderer keep all code completely separate of markup (there may
be others too, but I'm not aware of them myself).


> It has just enough functionality in the templates to allow people
> to do a few presentation layer if statements. 

Personally, I prefer to avoid these kinds of systems wherever possible
as they tend to be large, complex, expensive to implement and extend,
and hard to do well. (c.f. Greenspun's Tenth Rule of Programming: "Any
sufficiently complicated C or Fortran program contains an ad-hoc,
informally-specified bug-ridden slow implementation of half of Common
Lisp.":)

There are some advantages to creating custom embedded templating
languages:

- Simple embedded languages are a good option for shrinkwrap software
aimed at non-programmers who may want to customise their templates a
bit, but don't want to learn a full-blown programming language to do
so.

- They can be implemented as efficient code generators or using
lower-level languages, making it easier to squeeze out maximum
performance. (Though bear in mind that templating engine efficiency
only makes sense when considered as a proportion of your entire
system's performance. If there's a lot of heavy-duty data-crunching
being done in the backend, say, the speed of the templating engine is
unlikely to have much impact overall.)


For example, Cheetah is maybe 2-3x faster than the latest (unreleased)
version of HTMLTemplate. Not really surprising: Cheetah's optimised
code generator beats out HTMLTemplate's DOM-style object-thrash for
raw rendering speed.

However, HTMLTemplate's codebase, API and documentation are maybe a
tenth the size of Cheetah's, making it much easier to learn and
modify. (It also made it much easier to write.:)

...

> The key concept they
> push is the backend populates a nested dataset that can be serialized

This approach is not unique to ClearSilver, or even embedded
language-based templating systems (e.g. see Ruby's Amrita system). I'm
not really a fan myself; the extremely narrow API leaves you no choice
about where and how you prepare your data, and having to transform
your data twice - converting from original format into intermediate
form and then into HTML - seems like extra work. There might be
situations where such separation is useful, but I wouldn't want it
forced on me - HTMLTemplate, etc. let the user choose.


> so designers and programmers can agree on the data format from the
> start and go about their separate ways. 

This assumes that [HTML] designers are also coders, with
responsibility for implementing and maintaining the presentation logic
that drives their templates. Some are, but others aren't. Again, I
don't think it's right for templating engines to _force_ programming
duties onto the designer. HTMLTemplate et-al let you choose.

...

>  A really big plus for me is that it's a C library on the backend so if for whatever
> reason you needed to reimplement the backend in something other than
> python (god forbid :)), you have that flexibility.

I'm still curious: how often does this actually happen? Or is it a
case of YAGNI?

(BTW, ClearSilver refuses to build on my OS10.2.6 system, so right now
it's -1 for me.:)

Anyway, I'd imagine if you're recoding, say, a multi-KLOC backend from
scratch, a few hundred more LOC spent porting the templating layer
probably isn't going to make much difference. One of the nice things
about HTMLTemplate is that its tiny size (350LOC) should make it very
easy to port too if your new language doesn't already have it.

...

> I tried to wrap my head around nevow and I decided I don't like
> pulling data at the point at which we need it and I don't like coding
> renderers in python. 

Can you be more specific about why you don't like it?


> That really just makes me think at some point a
> designer would be coming over asking to change the way something looks
> by editing the rendering code.

This sounds like a demarcation issue:

- If the designer's job is purely to write HTML, then it's the
programmer's job to hook that HTML up to the presentation logic that
inserts content into it. Whether they like this arrangement or not is
irrelevant (see Golden Rule, The:). Keeping presentation logic
separate from HTML will make this process much less painful, however,
as it means the designer isn't stomping on code each time they make
HTML edits.

- If it's the designer's job to write their templates' presentation
logic as well, agreeing on a good API is no different to agreeing on a
good data exchange. A well-factored design should see presentation
logic in one set of files and business logic in another, allowing each
party to work on their own bit without bothering the other all the
time.


> The thing that I found coolest about nevow from a templating system
> perspective was that it's templates could have renderable data in
> them so the designer could have a template with real data in it. 

This is not unique to DOM-style templating systems (though they
certainly make it easy to do). e.g. See TAL, which embeds its custom
language in special tag attributes. The real benefit is in the
separation of markup and logic and what it does for the development
process; though the ability to use your finished templates as design
mockups is certainly nice.


> I still have a sneaking suspicion that I'm missing the forest with
> nevow however..

Hope this has helped a bit. :)

...

> Where do people prefer to put the logic that says "this row should be
> blue and the next one is white"?

I put it in the Template's Controller layer*, along with all the other
presentation control logic.

(* As-per Apple's definition of MVC, where 'Controller' is the layer
that connects the View to the Model.)


For example, given the following snippet of View code:

<table>
<tr node="rep:row" bgcolor="blue">...</tr>
</table>


It takes one line to assign the colour to the tag attribute, plus a
generic helper function (actually a generator), makeAlternator, that
yields each colour value in turn:

# Generic helper functions (usually put in a module of their own for
clarity and reuse):

def makeAlternator(*vals):
    i = 0
    while 1:
        yield vals[i % len(vals)]
        i += 1


# Template controller:

def renderTemplate(node, rows):
    node.row.repeat(renderRow, rows, makeAlternator('blue', 'white'))

def renderRow(node, row, alt):
    node.atts['bgcolor'] = alt.next()
    ...


# Output:

<table>
<tr node="rep:row" bgcolor="blue">...</tr>
<tr node="rep:row" bgcolor="white">...</tr>
<tr node="rep:row" bgcolor="blue">...</tr>
<tr node="rep:row" bgcolor="white">...</tr>
...
</table>



More information about the Python-list mailing list