Function
zope.app.container.contained.dispatchToSublocations

Signature

dispatchToSublocations(object, event)

Documentation String

Dispatch an event to sublocations of a given object

When a move event happens for an object, it's important to notify subobjects as well.

We do this based on locations.

Suppose, for example, that we define some location objects.

>>> class L(object):
...     zope.interface.implements(ILocation)
...     def __init__(self, name):
...         self.__name__ = name
...         self.__parent__ = None
...     def __repr__(self):
...         return '%s(%s)' % (
...                 self.__class__.__name__, str(self.__name__))
>>> class C(L):
...     zope.interface.implements(ISublocations)
...     def __init__(self, name, *subs):
...         L.__init__(self, name)
...         self.subs = subs
...         for sub in subs:
...             sub.__parent__ = self
...     def sublocations(self):
...         return self.subs
>>> c = C(1,
...       C(11,
...         L(111),
...         L(112),
...         ),
...       C(12,
...         L(121),
...         L(122),
...         L(123),
...         L(124),
...         ),
...       L(13),
...       )

Now, if we call the dispatcher, it should call event handlers for all of the objects.

Lets create an event handler that records the objects it sees:

>>> seen = []
>>> def handler(ob, event):
...     seen.append((ob, event.object))

Note that we record the the object the handler is called on as well as the event object:

Now we'll register it:

>>> from zope.app.testing import ztapi
>>> ztapi.subscribe([None, IObjectMovedEvent], None, handler)

We also register our dispatcher:

>>> ztapi.subscribe([None, IObjectMovedEvent], None,
...                 dispatchToSublocations)

We can then call the dispatcher for the root object:

>>> event = ObjectRemovedEvent(c)
>>> dispatchToSublocations(c, event)

Now, we should have seen all of the subobjects:

>>> seenreprs = map(repr, seen)
>>> seenreprs.sort()
>>> seenreprs
['(C(11), C(1))', '(C(12), C(1))', '(L(111), C(1))', '(L(112), C(1))', '(L(121), C(1))', '(L(122), C(1))', '(L(123), C(1))', '(L(124), C(1))', '(L(13), C(1))']

We see that we get entries for each of the subobjects and that,for each entry, the event object is top object.

This suggests that location event handlers need to be aware that the objects they are called on and the event objects could be different.