[Zope-CMF] Zope 3 events from workflow

Martin Aspeli optilude at gmx.net
Tue Jan 2 11:02:18 EST 2007




Chris Withers wrote:
> 
> Hi All,
> 
> Martin Aspeli wrote:
>> class IWorkflowEvent(IObjectEvent):
>>     """A workflow related event
>>     """
>> 
>>     wf_name = TextLine(title=u"The name of the workflow this event is 
>> part of")
>> 
>>     transition = TextLine(title=u"The name of the transition taking
>> place")
>> 
>>     state_before = TextLine(title=u"The object's state before the 
>> transition")
>> 
>>     state_after = TextLine(title=u"The object's state after the 
>> transition")
> 
> I know I'm very late on this (sorry for taking a christmas vacation ;-) 
> but how would I go about subcribing to a particular transition of a 
> particular workflow?
> 
> This feels like the most common case for me, but it would seem that if 
> you want to do that with the current patch, you'd have to have a generic 
> subscriber that then if/then/else'd its way to only doing the right 
> thing for the right workflow and the right transition.
> 
> I thought avoiding that kind of if/then/else'ing was what event 
> subscribers were all about.
> 
> Hopefully I'm just missing something, could someone enlighten me?
> (and by enlighten, I don't mean anything involving automotive fuel and 
> matches :-P)
> 

We've merged now :)

To subscribe only to particular transitions, you would need for each
transition object to provide a specific interface. If you look at the way
the object event re-dispatch happens in zope.component (or was it
zope.event?), it registers a general subscriber for IObjectEvent and then
redispatches for multi-subscribers based on (obj, event), i.e. you register
a handler for the object type and for the event type.

We could do the same for a transition event, e.g. re-dispatching based on
object type, workflow type and/or transition type.

However, in DCWorkflow, transitions are all of the same type, just with
different ids, and in WorkflowTool, actions (of which DCWorkflow transitions
are one common type) are also identified by a string only.

It would be possible to define some kind of re-dispatch that used named
adapters, but even though subscribers are just adapter factories under the
hood (you'll see the slightly odd syntax of a loop that just retrieves all
possible adapters from the component registry, doing nothing with the return
values, because the event subscriber registry is using the same mechanism as
the adapter factory registry, but the "factory" that is called normally does
the event work), I don't think there's any natural syntax for registering
named subscribers. You *could* do this though:

@zope.component.adapter(Interface, IWorkflowTransitionEvent)
def dispatch_transitions(obj, event):
    transition = event.transition.id
    factory = getMultiAdapter((obj, event),
provides=INamedTransitionSubscriber, name=transition)

<subscriber handler=".dispatch.dispatch_transitions" />

- which would be generic and only be needed once.

and then for each transition:

@zope.component.implementer(INamedTransitionSubscriber)
@zope.component.adapter(IMyObject, IWorkflowTransitionEvent)
def react_to_published(obj, event):
    ...

and in ZCML:

<adapter factory=".subscribers.react_to_published" name="publish" />

I'm not sure this is any easier or less hacky than doing the subscriber
like:

@zope.component.adapter(Interface, IWorkflowTransitionEvent)
def dispatch_transitions(obj, event):
    transition = event.transition.id
    if transition == 'publish':
       ...

Martin
-- 
View this message in context: http://www.nabble.com/Zope-3-events-from-workflow-tf2882759.html#a8126055
Sent from the Zope - CMF list2 mailing list archive at Nabble.com.



More information about the Zope-CMF mailing list