Today, I got to re-experience the benefits of working with
Page Templates (a very cool "Zope" technology) via a designer. Page Templates take a fairly (but
not totally) unique approach to server side HTML/XML markup - by using special tag attributes, via
TAL (the Template Attribute Language). This allows server side markup to be added to a page while having little or no effect on typical design tool (GoLive, Dreamweaver) usage. TAL is coupled with
TALES, an extensible system for expressions that can be used in TAL statements.
While I've been using Page Templates for quite some time, it's been primarily for my own work or for administration screens (where they've worked out quite well). Today, the designer who's been working on this project was ready to start uploading his work. After configuring Zope to turn uploaded HTML files into Page Template objects, I was able to open up
Dreamweaver MX (although I probably could have and should have stuck with
GoLive 6 - which has gotten very good at doing both Code + HTML and has nice local/remote file management - but I'm trying to give Dreamweaver a chance) and plug away at adding a few TAL attributes to the pages that needed them.
It's gone rather smoothly so far. There's a nice combination TAL/TALES expression to remove text from a rendered page, but keep it in the design one. For example:
<ul>
<li tal:repeat="item here/getNames" tal:content="item/lastName">McKinley</li>
<li tal:replace="nothing">Macinroe</li>
<li tal:replace="nothing">Macintosh</li>
</ul>
Using the 'replace="nothing"' construct, I was able to keep his code basically as it was, while still allowing a loop to happen (basically treating his code as example content). This was especially handy in a situation where I had to effectively "rotate" data - where rows in a database had to be displayed as columns in a table. I was able to go down each row, marking up the first data cell to be repeated (actually the second cell in each row), add in a 'tal:repeat' and a 'tal:content' statement, and then add a 'tal:replace="nothing"' to the remaining cells on the row. What I'm left with is a page that still looks fine in Dreamweaver, still draws fine in the browser without rendering, and also renders beautifully. The rest of this very well designed page I left completely untouched.
Very cool. This could not be done in DTML, and would be tricky (ie - require a very smart tool) with ASP/JSP/PHP and TEA/Cheetah style templates. And the fact that there are few pages that need server side markup (at this point), coupled with a very rich design, XSLT would have been grossly overkill.
Granted, this process has gone very smoothly because the new design is based off of an existing site that we're being paid to replace. The existing site has driven the database schema design (five tables, all in Gadfly), as well as the general content part of the new site - there are few surprises. The design has been shown to the customer independently of the dynamic nature of the site, and the dynamic parts shown have been rather well designed administrative pages (the customer was pleasantly surprised with them, and quite happy, and made only a single change requirement to them). So, at this integration point, it's just a combination of running GoLive/Dreamweaver in split Code/WYSIWYG mode, and quickly adding in a few TAL attributes into the settling design, while still allowing the designer to make tweaks. And while there are cases where things could still get messed up in regards to the placement and rendering of the Page Template, the chance is pretty low, especially this late in the design.
Ultimately, the designer has been quite happy with the new ZPT driven sites we've been doing, since the developers no longer wrest control away from him once a page is done (with DTML, a page would typically be diced into plenty of smaller parts, bad DTML tricks, and other what-nots in such a way that the designer would never recognize what had been done anyways). And, if something breaks, the Undo/History features of ZODB (the object database behind "Zope") offer good help towards fixing a problem before it gets too bad.
Very Nice.