Template mechanisms...

Avi Bryant avi at beta4.com
Thu Dec 12 00:22:30 UTC 2002


On Wed, 11 Dec 2002 goran.hultgren at bluefish.se wrote:

<lots about templating systems>

> Ok, Avi, Julian, what do you think?

Since you ask...

I find any system that treats the template purely as text to be too low
level - forcing me to textually insert a value or variable for every
attribute of every form field is equivalent to writing a GUI app by making
write()  calls to a X-windows client socket;  you might feel it gives you
more control, but mostly what it does is make busywork and reduce
abstraction.  This rules out the large majority of the templating systems
out there: variable subsitution systems like WebMacro or FreeMarker,
typical use of embedded code systems like PHP and JSP, tag-languages like
ColdFusion - in each case, every character of the final HTML output is the
direct result of some piece of code the developer wrote.  I
won't even get into the evils of mingling logic and presentation that are
inherent in most such systems, because they already fail on that basic
principle: HTML and HTTP have very well defined structure and semantics,
and a good templating system should know these intimately and largely
protect me from them.

I know of three general approaches to avoiding this problem: parse the
template and modify it programmatically, produce the HTML through
(declarative) transformation of the data, or generate the HTML directly
in code.

The first of these is the only one that's really "templating".  It's
the approach taken by WebObjects, Seaside 0.9x, and Enhydra/XMLC (used, I
think, by Barracuda, which was mentioned elsewhere in this thread).
Usually this involves producing some kind of a DOM from the template,
finding and transforming some special elements (which were given unique
ids in the template) while leaving the bulk of the elements alone, and the
regenerating HTML from the modified DOM.  Some systems provide better
abstractions for this than others (Seaside and WebObjects provide
sophisticated models of elements such as forms, links, and inputs, that
you interact with in a fairly high level way, whereas I believe XMLC users
tend still to directly manipulate HTML attributes), but once you have the
DOM in memory you can obviously interact with it as abstractly as you
like.

The only example of the second, transformative approach that I know of is
XSLT.  I've never used Coocoon or any other XSL-based system, so I don't
feel terribly qualified to speak about them, but I don't know any
designers *or* developers who don't shudder in horror at the thought of
writing XSL.  If somebody has good experiences with this approach, or
knows what the current best practices are, I'd love to hear about it.

Finally, there's the approach HttpView and Seaside2 take, which is not to
have templates at all, but rather to generate all of the HTML
programmatically.  As someone who's spent a lot of time implementing and
using template systems, this seemed at first horribly backwards.  What
I've discovered is that ditching templates entirely provides much more
opportunity for refactoring and abstraction.  The problem with templates
is that they force you to always think at the level of individual HTML
tags.  Once a tag is a method, it's much easier and more natural to start
combining them into larger and larger methods and classes, and the wins
from this are huge.

The other thing I've discovered simultaneously is that CSS is making
templates less and less necessary - if your code produces bare bones HTML
that's fully annotated with divs, spans, classes and ids, the designer
has a lot of huge amount of control over the look through the CSS file.
Going forward, this is where I think the division of responsibility should
lie: the programmer produces the (X)HTML, and the designer controls the
CSS.

As a still fairly low level example, I added a method to Seaside recently
named #rowWithLabelledTextInputOn:of: which is used like

html rowWithLabelledTextInputOn: #firstName of: customer.

and produces something somewhat like

<tr id="firstName"><td class="label">First Name:</td><td><input type="text" value="Avi"></td></tr>

Note a few things about this:
 - it's one method call instead of 5 or so tags
 - this pattern likely gets used hundreds of places in your app; now you
can change it from one place
 - it automatically inserts classes and ids so that CSS can modify any
part of the look
 - you can use this as a building block for higher level abstractions

Now, in theory in JSP-like systems with custom tags you could build a
<labelledRow> tag, that would be used something like

<table>
<labelledRow name="firstName" target="customer">
...
</table>

or some such.  But what's the point?  You've lost the benefits of
templates (Dreamweaver has no clue what to do with that, an HTML designer
can't do much with it either), and also lost the benefits of having it be
in code (is senders of #firstName gonna find your template?  How about
inst var references to 'customer'?).  In practice, people don't do this -
they just copy and paste the same HTML boilerplate all over the place.

> Or perhaps use some other templating mechanism that can let the "HTML
> gurus" do their job. For example - here is one interesting approach that
> may be impossible:
>
> 1. Build the webapp as simply as possible but actually working.
> 2. Turn on some form of "ids in tags" generation which means that the
> HtmlBuilder adds ids in the generated tags to keep track of them.
> 3. Let the designer run the app and simply do "Save as..." on the HTML
> pages/HTML components. (Given that any given component easily can be
> addressed separately or at least "cut out" from an HTML page, for
> example if contained within a div-tag). Of course you could let the
> serverside app save out the HTML pages instead of returning them through
> HTTP, etc. whatever.
> 4. Let the designer edit them into glorious looking HTML that no mortal
> can ever read.
> 5. Feed the new HTML pages (and CSS+any scripts of course) back into the
> HtmlBuilder that somehow can take the original page and the "glorified"
> page and from that (and the embedded "track" tag ids) construct an
> internal template of some kind.
> 6. Turn of the tag ids, they aren't useful anymore - they were only used
> for tracking the generated tags.

I'll respond to this later, this email's more than long enough already.
Basically I think it's a good idea if you can manage to pull it off.




More information about the Squeak-dev mailing list