Modified Event Handler for Dexterity Form Field?

Hello,

I try to create an email notification for project owners on a Plone site, if the content of a field in the parent folder object is changed. The field contains a list of software versions. The project owner should get the message about the new version and check if his product is compatible with the new software version.

I tried this with IObjectModifiedEvent and a for loop with modified.<field_name> but my function was executed not only for a change in that field but for each field of my content object. Because there were 15 form fields I got 15 returns (I tested with a print command).

The print event was also fired, if I edited another field of my content type.

I wonder if there is a way to bind a modified event only to one form field of a Dexterity content type.

Regards,
Andreas

1 Like

Not great but the first thing that comes to my mind: In the event-handler compare the current version with the last revision (given versioning ist enabled) and only send a mail if there is a difference in the relevant field.

You could also look at the DataExtractedEvent that is fired by z3c.form when extracting the data from the edit-form. But you cannot be 100% sure that the object will actually be saved since that is done in a later method and validators of others groups might fail...

Dexterity edit forms attach info to the ObjectModifiedEvent about which field(s) was modified. You can write a handler like this:

def handle_modified(object, event):
    if hasattr(event, 'descriptions') and event.descriptions:
        for d in event.descriptions:
            if d.interface is IMySchema and 'my_field' in d.attributes:
                # do things here

Unfortunately there isn't a way to get the old field value from the event handler, though.

2 Likes

Hello,

thanks for your help. It works perfect and I could add a notification to all users once the versions list is edited.

@grok.subscribe(IEUpCenter, IObjectModifiedEvent)
def notifiyAboutNewVersion(eupproject, event):
if hasattr(event, 'descriptions') and event.descriptions:
for d in event.descriptions:
if d.interface is IEUpCenter and 'available_versions' in d.attributes:
users=api.user.get_users()
message='We added (...)'
for f in users:
mailaddress = f.getProperty('email')
api.portal.send_email(
recipient=mailaddress,
sender="noreply@libreoffice.org"
subject="New Version of LibreOffice Added",
body=message
)

Kind regards,
Andreas

Hello,

seemed the formatting of my reply broke. My code (patch) is here:

Kind regards,
Andreas