On 8/13/06, Philipp von Weitershausen <[EMAIL PROTECTED]> wrote:
For the second edition of my book I have implemented a new skin from
scratch, using a pure viewlet approach. It was surprisingly simple to do
and didn't take a lot of code. The result is very modular. I think a new
ZMI skin for Zope (e.g. Boston) should be more like that. All the bits
and pieces it has could come from individual viewlets. In the end, the
"main" template just decides where the bits and pieces are located.
Custom skins can then simply reuse all the viewlets and just move them
around in the template as they like.

"simply". Isn't there a ban on that word? Or was that just for beer
sessions at ZC? :)

This application is the first time we've started to really try go with
the full-page model. There's a mix-in, ``WebPageSupport``, which
basically makes the whole page act like a viewlet manager, thus
eliminating the problem of:

1. There's a 'cartContents' viewlet/content provider in the main
template. Under
  normal contentProvider rules, the `provider: ` expression type (or any other
  method of calling it) would call both `update()/render()` at the same time.

2. There's an 'add to cart' form that is in this page's main template
(or other)
  code, and the user has added something to the cart. The 'update' action of
  the form adds the item on a post-back. But because it comes *after* the
  'cartContents' content provider, the 'cartContents' provider won't show an
  incremented number until the next stage.

We've actually borrowed a few concepts from Rails with their concept
of pages having a layout. The layout is basically the typical
``fill-slot="body"`` template pre-filled out, so that the View/Page
subclasses just have to provide ``contentForLayout``. Among other
things, it makes coding Page Templates a little bit faster as the
'insert header/footer' material, or it's page template equivalent, is
removed. A side benefit is that it potentially makes many of these
'pages' could easily be turned into viewlets, into AJAX views, etc, as
they all have a method that renders just the guts of that

Either way, being skeptical of content providers and viewlets at first,
I now think they're a great tool. And I've seen from practical
experience that they solve lots of skinning problems. I know the Plone
guys are rewriting their portlet machinery currently to take advantage
of content providers. Very nice.

Skinning aside, it's nice to be able to componentize the page. We've
already made some common Viewlets that can be used in a project with
very little fuss, such as Menu renderers. CSS applies most of the
visual styles. The standard template, these days, can usually fit in
as 80 lines of (or less) of nicely structured HTML.

The `update/render` pairing is just a wonderful concept. For this
project we're doing, I got base classes established immediately for
pages and views that depended on these methods so that teammates would
all use them (or some other common one). It makes views more
predictable, and easier to subclass as we can override `update()` to
customize view initialization behavior that would previously be done
in __init__ (which could then cause confusion if the ZCML directive
used was different than what your class sub-classed). Everyone knows
to call ``super(...., self).update()`` and/or ``super(....,
self).render()``. There's much less guessing going on with how best to
implement a view.

These concepts came in from content providers, but it wasn't until I
saw the `formlib` code that I really understood their usefulness.

I'm still not a big fan of the provider: expression type in TALES. I
think it's a misuse of TALES expression types. TALES expression types
aren't there to look up things. They are there to express different
kinds of expressions:

  - python: foo.bar
  - path: foo/bar
  - string: foobar

provider: doesn't fit into that category. In fact, I think it's the only
TALES expression that looks up things. Looking up things is the duty of
traversal. I really think we should have a provider namespace adapter:

I (mildly) agree. In my `WebPageSupport` mix-in, I've added a method
`renderProvider`. Primarily it was to get around calling the provider
a second time and having its `update` method called again, although
I've now added some a `hasUpdated` concept to our ContentProvider base
classes. But these are what I've added to our class. Again
`WebPageSupport` is a mix-in (so it can be used with some basice
BrowserView based base classes, as well as some `formlib` base/edit
form based classes) that turns a web page into a ContentProvider
Manager, ensuring that providers that are mentioned in the standard
template(s) as well as ones specifically referenced by a Page are all
updated at the same time::

   def updateProviders(self):
       for provider in self.contentProviders():

   def renderProvider(self, name):
       provider = self.get(name)
       if provider is None:
           return u""
       return provider.render()

`updateProviders` is typically called in the `update` phase of the
view/page, and `renderProvider` is typically called in the page
template or other code (like our nevow.Stan / Seaside inspired
system). This behavior is just a little bit more predictable than
`provider:`, is usable outside of TAL/TALES, and jumps straight to
`render` since it's typically being called in the rendering phase of
the surrounding view anyways.

(although, we still use `provider:` quite a bit for most of the core
viewlet managers that are used in the main template that have become
practically invisible to us, such as the ones that load up all of the
head resources).

Anyways, I care less about default skins than I do about default
tools. `formlib` made Zope 3 a much stronger toolkit for us, although
we still struggle with advanced widgets and scenarios. `zc.table`
looks cool, but looks unfinished and we haven't had time to really
investigate it further. I'm hoping that more toolkits and like those,
however, show up so that it's fairly easy for a developer to come up
with some Django-style admins of their own, that look and feel and
behave like they and their company / client want. I think that's a
better tool to offer than a whiz-bang skin that is difficult to
customize when a client or boss goes "can we get rid of those tabs at
the top? how about sorting the menu on the side? can we add some links
to the footer for support contact? why does that say 'add ZPT page?'",

If things slow down... uhm, ever... for us, I'd like to see if I can
get us to open up some of the more generic toolkits we've built up in
recent months, as they've been very empowering.

Jeff Shell
Zope3-users mailing list

Reply via email to