[Zope3-dev] My Experiences using Interface invariants with Formlib

Michael Howitz mh at gocept.com
Mon Jan 30 03:21:04 EST 2006


Hi, as suggested in #zope3-dev I'll post my experiences with interface
invariants and formlib here.

I have an interface with two password fields which should be equal:

class IUser(Interface):
    password=zope.schema.Password(title=u"password")
    password2=zope.schema.Password(title=u"password again")

# this Exception is raised when password are not equal
class PasswordsAreNotEqual(zope.schema.ValidationError):
    u"""Passwords are not equal."""
    # the docstring is shown in UI becuase it is a ValidationError
    implements(zope.app.form.interfaces.IWidgetInputError)
    # see below why

# this function tests equality
def arePasswordsEqual(obj)
    if obj.password != obj.password2:
        raise PasswordsAreNotEqual

# set the test function as invariant
IUser.setTaggedValue('invariants': [arePasswordsEqual])

Formlib expects Errors raised by invariants to be subclasses from
zope.interface.Invalid (which zope.schema.ValidationError is).

To dislay the error formlib tries to get a multi adapter which provides
zope.app.form.browser.interfaces.IWidgetInputErrorView. There is only
one such adapter in Zope3
(zope.app.form.browser.exception.WidgetInputErrorView) because it seems
that all other errors in FormBase's self.errors are implementing
zope.app.form.interfaces.IWidgetInputError or even they are instances of
zope.app.form.interfaces.WidgetInputError. (Did not try.)

So I implemented zope.app.form.interfaces.IWidgetInputError in my error
class. (Which really implements this interface because the only method
the interface provides (doc) is implemented by
zope.schema.ValidationError.

If the exception has an attribute widget_title (which is not in the
interface zope.app.form.interfaces.IWidgetInputError but only in the
class zope.app.form.interfaces.WidgetInputError) then the value of this
attribute is displayed in front of the error message separted by a
colon.

The error message is only displayed on the top of the form. Maybe there
is also a way to get the error message displayed under a widget.

Is this the way it should be done?

-- 
Mit freundlichen Grüßen

Michael Howitz



More information about the Zope3-dev mailing list