Last modified: May 05, 2025 By Alexander Williams
Plone Event Systems Guide
Plone's event system helps automate tasks when content changes. It triggers actions on create, update, or delete events. This guide explains how to use it.
Table Of Contents
Understanding Plone Events
Plone uses Zope's event system. Events notify when objects change. Common events include object creation, modification, and removal.
Events help decouple components. They allow reacting to changes without direct calls. This makes code more maintainable and extensible.
Core Event Types in Plone
Plone uses several key event types:
- ObjectAddedEvent: Triggered when adding content
- ObjectModifiedEvent: Fired when content changes
- ObjectRemovedEvent: Called when deleting content
These events work with Plone's content types. They integrate with the Plone Catalog for indexing.
Subscribing to Events
To handle events, create a subscriber. Use the @subscriber
decorator from zope.component.
from zope.component import adapter
from zope.interface import implementer
from plone.app.contenttypes.interfaces import IDocument
from plone.dexterity.interfaces import IDexterityContent
from zope.lifecycleevent import IObjectAddedEvent
@adapter(IDocument, IObjectAddedEvent)
def handle_document_added(document, event):
"""Handle new document creation."""
print(f"New document created: {document.title}")
Register subscribers in ZCML:
Creating Custom Events
You can define custom events. First, create an interface for your event:
from zope.interface import Interface
from zope.component.interfaces import IObjectEvent
class ICustomEvent(IObjectEvent):
"""Marker interface for custom events."""
Then implement the event class:
from zope.component.interfaces import ObjectEvent
class CustomEvent(ObjectEvent):
"""Custom event implementation."""
implements(ICustomEvent)
Triggering Events
Fire events using notify()
from zope.event:
from zope.event import notify
from .events import CustomEvent
def some_action(obj):
# Do something
notify(CustomEvent(obj))
Practical Example: Auto-Tagging
Here's a complete example that auto-tags new content:
from plone.dexterity.interfaces import IDexterityContent
from zope.lifecycleevent import IObjectAddedEvent
from zope.component import adapter
@adapter(IDexterityContent, IObjectAddedEvent)
def auto_tag_content(content, event):
"""Add automatic tags to new content."""
if not hasattr(content, 'subject'):
return
auto_tags = ['auto-tagged', content.portal_type.lower()]
current_tags = list(content.subject) if content.subject else []
content.subject = tuple(set(current_tags + auto_tags))
This integrates with Plone's content models system.
Event Handling Best Practices
Follow these tips for effective event handling:
- Keep subscribers small and focused
- Handle exceptions properly
- Avoid infinite event loops
- Document your subscribers clearly
For complex cases, consider using view components instead.
Debugging Events
To debug event issues:
from zope.event import subscribers
def log_event(event):
print(f"Event fired: {event.__class__.__name__}")
subscribers.append(log_event)
This logs all events to console. Remove it in production.
Performance Considerations
Events impact performance. Keep these in mind:
- Too many subscribers slow down operations
- Complex subscribers delay response times
- Some events trigger catalog updates
Profile your event handlers regularly.
Conclusion
Plone's event system is powerful. It enables clean, decoupled architectures. Use it for automation and integration tasks.
Start with simple subscribers. Gradually build more complex handlers. Always consider performance implications.
For more advanced topics, see our guide on Plone fundamentals.