Dexterity开发手册:第六章 第9节 事件操作
Dexterity开发手册:第六章 第9节 事件操作
http://www.315ok.org/blogfolder/405
http://www.315ok.org/logo.png
Dexterity开发手册:第六章 第9节 事件操作
Dexterity开发手册:第六章 第9节 事件操作
为你的内容类型添加定制的事件操作
至今未知,我们的教程涉到了内容类型的 schemata 和用这些技术创建的表单。然而,我们经常需要添加更多的动态功能,来响应当我们的类型对象发生什么事件时,给予相应的处理操作。在 Zope,这个功能通常用event subscribers来实现。
Zope的事件模式是同步处理概义。当一个事件被广播时 (可以通过来自zope.event 包的 notify() ), 例如,当一个表单的保存操作发生时,所有预定该事件的事件预定者的处理操作(handler)将被调用。没有任何措施来保证所有事件预定者的事件操作被执行的顺序。然而每个事件都被一个接口来描述,典型的都附带有该事件的相关信息。 有些事件提供zope.component.interfaces.IObjectEvent接口,我们称之为对象事件,这类事件有一个对象属性,可以索引到发生该事件的对象。对象事件允许事件操作注册为针对特定事件类型绑定到特定的对象类型。
Plone中最通常使用的事件都列在下面,他们都是对象事件:
As an example, let's add an event handler to the Presenter type that tries to find users with matching names matching the presenter id, and send these users an email.
First, we require a few additional imports at the top of presenter.py:
至今未知,我们的教程涉到了内容类型的 schemata 和用这些技术创建的表单。然而,我们经常需要添加更多的动态功能,来响应当我们的类型对象发生什么事件时,给予相应的处理操作。在 Zope,这个功能通常用event subscribers来实现。
Zope的事件模式是同步处理概义。当一个事件被广播时 (可以通过来自zope.event 包的 notify() ), 例如,当一个表单的保存操作发生时,所有预定该事件的事件预定者的处理操作(handler)将被调用。没有任何措施来保证所有事件预定者的事件操作被执行的顺序。然而每个事件都被一个接口来描述,典型的都附带有该事件的相关信息。 有些事件提供zope.component.interfaces.IObjectEvent接口,我们称之为对象事件,这类事件有一个对象属性,可以索引到发生该事件的对象。对象事件允许事件操作注册为针对特定事件类型绑定到特定的对象类型。
Plone中最通常使用的事件都列在下面,他们都是对象事件:
- zope.lifecycleevent.interfaces.IObjectCreatedEvent, fired by the standard add form just after an object has been created, but before it has been added on the container. Note that it is often easier to write a handler for IObjectAddedEvent (see below), because at this point the object has a proper acquisition context.
- zope.lifecycleevent.interfaces.IObjectModifiedEvent, fired by the standard edit form when an object has been modified
- zope.app.container.interfaces.IObjectAddedEvent, fired when an object has been added to its container. The container is available as the newParent attribute, and the name the new item holds in the container is available as newName.
- zope.app.container.interfaces.IObjectRemovedEvent, fired when an object has been removed from its container. The container is available as the oldParent attribute, and the name the item held in the container is available as oldName.
- zope.app.container.interfaces.IObjectMovedEvent, fired when an object is added to, removed from, renamed in, or moved between containers. This event is a super-type of IObjectAddedEvent and IObjectRemovedEvent, shown above, so an event handler registered for this interface will be invoked for the 'added' and 'removed' cases as well. When an object is moved or renamed, all of oldParent, newParent, oldName and newName will be set.
- Products.CMFCore.interfaces.IActionSucceededEvent, fired when a workflow event has completed. The workflow attribute holds the workflow instance involved, and the action attribute holds the action (transition) invoked.
As an example, let's add an event handler to the Presenter type that tries to find users with matching names matching the presenter id, and send these users an email.
First, we require a few additional imports at the top of presenter.py:
from zope.app.container.interfaces import IObjectAddedEvent
from Products.CMFCore.utils import getToolByNameThen, we'll add the following event subscriber after the schema definition:@grok.subscribe(IPresenter, IObjectAddedEvent)
def notifyUser(presenter, event):
acl_users = getToolByName(presenter, 'acl_users')
mail_host = getToolByName(presenter, 'MailHost')
portal_url = getToolByName(presenter, 'portal_url')
portal = portal_url.getPortalObject()
sender = portal.getProperty('email_from_address')
if not sender:
return
subject = "Is this you?"
message = "A presenter called %s was added here %s" % (presenter.title, presenter.absolute_url(),)
matching_users = acl_users.searchUsers(fullname=presenter.title)
for user_info in matching_users:
email = user_info.get('email', None)
if email is not None:
mail_host.secureSend(message, email, sender, subject)There are many ways to improve this rather simplistic event handler, but it illustrates how events can be used. The first argument to grok.subscribe() is an interface describing the object type. For non-object events, this is omitted. The second arugment is the event type. The arguments to the function reflects these two, so the first argument is the IPresenter instance and the second is an IObjectAddedEvent instance.