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.

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.