[Zope-dev] Re: Five and browser-oriented components

Daniel Nouri daniel.nouri at gmail.com
Thu Apr 10 09:53:22 EDT 2008


Malthe Borch <mborch at gmail.com> writes:

> Daniel Nouri wrote:
>> Therefore, I'd argue that we should, in contrary to what you suggest,
>> make the Zope 2 compatibility layer more explicit in the form of utility
>> functions, instead of more implicit.  Because it makes things more
>> transparent and easier to debug.
>
> You might be right; but it's a very bad place to be, stuck in the
> middle of two frameworks. We're duplicating code all over the place,
> and while this has obvious inherent qualities, it also wears us out as
> a community.

I think I found a useful pattern for how to work with z3c.forms to avoid
duplication.  For each page that has forms, I make two views; one is the
Products.Five.BrowserView view that's looked up by the publisher and is
registered with ZCML.  The other is my z3c.form.form.Form that does the
actual work and renders my content area.  The relationship between these
two forms is similar to that of forms and subforms.

Here is an example of how this looks like in practice:

    class MyForm(z3c.form.form.Form):
        template = Z3ViewPageTemplateFile('form.pt')

        fields = z3c.form.Fields(ISomething)

        @button.buttonAndHandler(_('Apply'), name='apply')
        def handle_apply(self, action):
            data, errors = self.extractData()
            # ...

    class PloneView(Products.Five.BrowserView):
        __call__ = Z2ViewPageTemplateFile('main.pt')
        form = MyForm

        def contents(self):
            z2.switch_on(self)
            return self.form(self.context.aq_inner, self.request)()

Here, main.pt is the part that renders main_template and pulls in
view/contents into the "content area".

z2.switch_on() is a compatibility function that fiddles a bit with the
Zope 2 request to make it work with z3c.form (and also calls Five's
decodeInput).

Of course, PloneView is generic enough to be subclassed at this point:

    class MyFunnyView(PloneView):
        form = MyFunnyForm

What's the advantage of this separation?

  - You don't have to worry about Acquisition in your form code, which
    will make out the bigger part of your code.  The implications of
    Five's BrowserView being derived from Acquisition.Explicit has often
    left me confused.  (Death to self.context.aq_inner!)

  - You can reuse form code between Zope 2 and Zope 3. 

  - Your forms can be rendered in any part of your page, like in
    portlets.

  - No subclassing of classes in z3c.form is necessary to use the forms
    in Zope 2.  (In contrast to Five's current way of subclassing
    formlib.)


Daniel



More information about the Zope-Dev mailing list