Re: Validation and Events

Martin Aspeli <[email protected]> Tue, 26 Sep 2006 09:30:52 +0100
Newsgroups gmane.comp.web.zope.plone.archetypes.devel
Message-ID <[email protected]>
Hi George,

>> This is pseudo-code, obviously. But the point is, if notify() didn't 
>> block until all event handlers were finished, then you couldn't check 
>> the 'errors' dict like that!
> 
> 
> I'm confused what you mean by "block" -- block meaning, "CALL ALL THE HANDLERS,
> NOW"? What other event handlers would it be waiting for?

Ah, sorry - block is kind of a general programming term (esp. when you 
talk about concurrency) that means "does not return" or "does not let 
execution continue". So, there are two ways you could implement events - 
either they all fire straight away when 'notify' is called, and the cod 
that called 'notify' can't go on until all registered subscribers are 
finished, or they're asynchronous, meaning they either go in a different 
thread or are delayed until a transaction boundary.

> Also, where would the definition of this Event go?

The interface probably in Products.Archetypes.interfaces._events.py with 
an import to interfaces/__init__.py. Some people (including Zope 3) put 
the concrete class of the event in the 'interfaces' package too. Not my 
liking, but it could go there.

> Finally, looking at how Archetypes' validation works, there seems to be a
> natural place for the event to fire. From the definition of
> Products.Archetypes.BaseObject.BaseObject:
> 
>     def validate(self, REQUEST=None, errors=None, data=None, metadata=None):
>         """Validates the form data from the request.
>         """
>         if errors is None:
>             errors = {}
>         self.pre_validate(REQUEST, errors)
>         if errors:
>             return errors
>         self.Schema().validate(instance=self, REQUEST=REQUEST,
>                                errors=errors, data=data, metadata=metadata)
>         self.post_validate(REQUEST, errors)
>         return errors

Right, then it should probably fire just after post_validate(), I guess. 
Or we may want pre-validate and post-validate events, but that seems a 
bit overkill to me.

> And from the archetypes skin folder, validate_base.vpy (validate_integrity.cpy
> is almost identical):
> 
>  errors = {}
>  errors = context.validate(REQUEST=context.REQUEST, errors=errors,
>    data=1, metadata=0)

That's calling the above validate() method, so I don't think we'd need 
to modify this.

>  if errors:
>      return state.set(status='failure', errors=errors,
>        portal_status_message='Please correct the indicated errors.')
>  else:
>     return state.set(portal_status_message='Changes saved.')
> 
> So all that is needed is to fire the event right before "return errors" above to
> add to to the errors dictionary.

Probably. As I suggested, I think the best idea is to pass the 'errors' 
dict along the event, so that event handlers can put stuff into it and 
possibly read it as well.

Why don't you have a stab at it and then send a patch? In any case, I 
think this generally looks useful and non-invasive.

Martin


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV