Web tool kit : pro - cons ?

Jeffrey P Shell elw at euc.cx
Wed Jul 30 07:49:26 CEST 2003


David Jeske <jeske at chat.net> wrote in message news:<mailman.1059332921.14965.python-list at python.org>...
> If you are not wedded to Zope for your applications, you may want to
> look at Clearsilver. (http://www.clearsilver.net) It is a very mature
> system which was developed at eGroups.com, and today is in use on
> high-performance sites such as Yahoo! Groups and
> wunderground.com. Clearsilver includes a full CGI kit which handles
> form variables, cookies, etc. It also includes a PythonObject<->RDBMS
> mapping system (MySQL only today, no pgsql yet), and a transparent
> translation string extraction system. It is not a "server environment"
> like Zope, and in fact you can use it inside of your server of choice
> (Apache, Boa, IIS, Zope, etc).
> 
> I find ZPT's model for replacement hard to work with, because it tries
> to fit into the xml document namespace. From the ZPT documentation
> here:
> 
>   http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx
> 
> This example:
> 
>   <title tal:content="here/title">Page Title</title>
> 
> Illustrates how ZPT is making it's "tag" (i.e. tal:content) fit in as
> an attribute defined by a new XML namespace. The problem is, this
> constrains where you can use template commands to construct the
> document. Clearsilver uses a model more like PHP where the tags exist
> as items outside of the XML document parsing. This has the drawback
> that your template document is not a valid XML document, but it has
> the advantage that you can put the tags anywhere. 
> 
> For example, in clearsilver, you can construct URLS using sequences of
> template commands, even looping. Here is a small example (whitespace
> added for readability):
> 
> <a href="/url?
>  <?cs each:p=CGI.Params ?>
>    <?cs var:p.name ?>=<?cs var:p.value ?>&
>  <?cs /each ?>"
> >a_link</a>

I love Zope's page templates.  I do have to admit that I worked at
Zope Corporation since before Zope was Principia, but am now out in
the wild stressful world on my own again.  But I grew to *hate* the
above style of templating, which Zope's older model (DTML) follows. 
I've been using DTML since early 1997 and when web applications were
still fairly simple, I think it was a nice system (DTML was also
simpler then and focused more on being a templating language than on
being a programming language, which is what made DTML particularly
painful on Zope in later years before ZPT).

I work with some very talented designers.  It used to be that they
would give us (the developers) their designs and we'd rip them to
shreds and they could never touch them again.  Because now they were
in little bits and pieces and stuffed full of tags-within-tags, with
silly things like 'standard_html_header' and 'standard_html_footer'
(never really fitting a technical definition of header once complex
designs enter the equation) making it very painful to apply what they
would thing were rudimentary design changes.

Not so with ZPT.  It's not a holy grail, but it's pretty close.  Most
of the time, the designers can tweak the site - even in production -
without upsetting the natural order of things.  Given that they're
full time graphic designers (sortof a 'sibling' company.  they also do
a lot of large volume print material, etc) and not programmers, this
is pretty impressive.  They are smart enough to watch out for the
dynamic parts.  But we've had very few issues since moving to it.

What I personally like about ZPT is the fact that it feels natural
within the HTML/XML environment.  It may have taken some getting used
to initially, but I find it very natural.  And it's extra nice because
I can work in smart text editors like XEmacs or BBEdit, or work in
GoLive (very nice when used with its WebDAV browser) and can view the
whole page - including the 'standard header/footer' (usually supplied
by a standard full page macro, which in itself is very easy to modify
and edit because it's a single full page and not broken up into chunks
like header/footer/sidebar - VERY nice.  My life is so much better for
this fact alone!).  Sometimes adding a dynamic element to a tag from
visual mode means just popping up the quick-tag editor and adding in a
TAL statement.  Close the tag editor, and the page is still intact.

You can even do complex things like the following::

  <tr tal:attributes="class python:test(repeat['item'].even(), 'even',
'odd')">
    ....
  </tr>

and have visual editors, or even helpful hilighting editors (BBEdit,
XEmacs, etc) not be affected by it.  Compared to::

  <tr class="<!--#if even-->even<!--#else-->odd<!--#/if-->">

or this, if you only want the class attribute written on even rows
(and how we come up with the variable 'even' is being left to the
imagination here):

  <tr <!--#if even-->class="even"<!--#/if-->>

most editors just die right here - especially visual ones.  In TAL,
you could do:

  <tr tal:attributes="class python:test(repeat['item'].even(), 'even',
nothing)">

and most editors would be fine.  (Note: 'nothing' is that ZPT
equivalent of 'None'.  The core components of ZPT (TAL, TALES, METAL)
were written as specs first, with the idea/hope that other programming
languages could implement them as well, hence 'nothing'.  'None' could
have been used in its place just as easily in this situation).  Is it
more verbose?  More typing?  At times, yes.  But there's a nice
explicit nature about it, and many old Zoper's have learned the hard
way that explicit is almost always better than implicit (DTML had so
many implicit actions going on that in the end - even after years of
use - there were always new surprises waiting in the wings.  And
Radiohead says it best - 'no alarms and no surprises').

Anyways - this is just my personal experience.  But I find that
(generally) with ZPT, I'm writing better HTML and have a more
maintainable web site.  It's different, but I think it's a good thing.
 I'm happy to get away from Server Side Include and Processing
Instruction style syntaxes.

To get back to your example::
> <a href="/url?
>  <?cs each:p=CGI.Params ?>
>    <?cs var:p.name ?>=<?cs var:p.value ?>&
>  <?cs /each ?>"
> >a_link</a>

ZPT (at least in Zope) has a helpful module called ZTUtils that
contains a lot of nice helper functions for building query strings
(which I'm increasingly convinced should never be constructed by hand
unless absolutely necessary, due to issues with URL and/or HTML
quoting), hidden values, etc.  Assuming that CGI.Params is a
dictionary/mapping, once could do:

<a tal:define="query python:modules['ZTUtils'].make_query(CGI.Params)"
   tal:attributes="href string:/url?${query}"
 >a_link</a>

``make_query`` (which can also use keyword arguments) is extra nice
because it automatically URL quotes all of the values for the query
string.  This is EXTRA EXTRA nice when passing full LDAP distinguished
names in a query string, for example.

> > No.  Each part of the web page will be "boxes".  I would like to be very
> > flexible and display "dynamically" some selected boxes.
> > For example the same page (url) will not display the same boxes if you are
> > administrator, maintener or simple viewer.
> 
> This should be pretty easy in most template systems worth their
> weight. 
> 
> > An another example will be to have possibility to re-use existing boxes.  If
> > I have a boxes displaying the last 5 news from Slashdot, I don't want to
> > re-write it each time I need a new bacground color (for example). My Idea
> > is to use those "boxes" like we use classes : if you need some modification
> > you subclass it on the rest remains the same.
> 
> Clearsilver has a macro definition facility for doing just this. You
> can supply arguments to macros, and even call macros recursively. Here
> is a simple example:
> 
>   <?cs def:makelink(url,title,text) ?>
>    <a href="<?cs var:url ?>"
>       title="<?cs var:title ?>"
>    ><?cs var:text ?></a>
>   <?cs /def ?>
> 
>   <?cs call:makelink("http://www.python.org","Python.org website","Python.org") ?>
> 
> The paramaters can be any expressions, including constructed strings,
> or data from your dynamic CGI. For example:
> 
>   <?cs call:makelink("http://" + CGI.host + "/" + CGI.script,"title","link text") ?>
> 
> As always, there are lots of systems out there, and YMMV.

Macros do make life happy.  :)  Or at least, happier.  ZPT macros
(METAL) do things a little differently, but I think it works out for
the best.  To the best of my knowledge, ZPT compilation/rendering
occurs in two steps - first, macros are expanded (METAL statements are
executed) into the template like they were there in the template all
along, and then all of the TAL statements (including ones that were in
the macros) get executed.  One thing this allows, when used in a
dynamic environment like Zope, is the ability to have the macros be
expanded at edit time (optionally, of course).  When using a full-page
macro, you can add a new ZPT page, fill it in like this::

<html metal:use-macro="here/standard_template.pt/macros/page">
<body>
<div id="main" metal:fill-slot="body">
<h3>The body of my new page template</h3>
</div>
</body>
</html>

Turn on 'expand macros', and the whole macro 'page' defined in the
page template 'standard_template.pt' gets expanded.  Macros define
'slots' which clients of the macros can choose to fill in.  Nicely, if
you don't fill a slot specified by the macro, its defaults are filled
in and you can see where the slots are by looking for the 'metal:slot'
attributes.  The above mentioned macro might contain a slot called
'local_js' and put it on a <script> tag:

<script type="text/javascript" metal:slot="local_js"><!--
// local javascript for this page, if needed
--></script>

You can use it if desired, by changing 'metal:slot' to
'metal:fill-slot' and add Javascript to the head of the page - all
without requiring changing the header or having to have the page
broken up into statements like:

<!--#var early_head-->
<script type="text/javascript" ><!--
// my local javascript
--></script>
<!--#var close_head-->
<!--#var body_header-->
...
...
...

Which I've had to do and maintain so many times.  I'm not sure when it
happened - but at some point, this all got to be unmanageable.  It's
easy for situations like an intranet or basic web application where
you're in control, but when you're on the east coast dealing with a
west coast designer who dramatically changes layout every day - it
does grow untenable.

But I've long been of the personal opinion that HTML and code don't
mix.  I felt that way ever since I started using CGI and wrote my own
little dynamic web system (pummel/pyml/avantpy) in '96 until I got
turned on to Bobo (ancestor and still-the-heart of Zope).  ZPT lets me
see my templates as HTML, but still gives me the programmatic control
I need.  It's better than the old days when I'd look at my templates
and see two conflicting languages that looked alike - an SGML-ish tag
based templating language inside the SGML tag based HTML language. 
For some reason - using basic XML constructs (namespaced attributes)
works so much better (for me) than using one set of tags within
another set of tags.

I think that's all aided by how relatively clean and simple they've
managed to keep the core ZPT languages (TAL, METAL).

But, as always, mileage will definitely vary.

--
Jeffrey P Shell
http://toulouse.amber.org/

"Tied you up, placed in tube"
http://euc.cx/




More information about the Python-list mailing list