[Zope3-checkins] SVN: zope.formlib/trunk/ Introduced ``zope.formlib.form.applyData`` which works like

Philipp von Weitershausen philikon at philikon.de
Fri Nov 9 14:03:22 EST 2007


Log message for revision 81649:
    Introduced ``zope.formlib.form.applyData`` which works like
    ``applyChanges`` but returns a dictionary with information about
    which attribute of which schema changed.  This information is then
    sent along with the ``IObjectModifiedEvent``.
  
    This fixes https://bugs.launchpad.net/zope3/+bug/98483.
  
    This comprises a new feature, therefore bumping version to 3.5.0.
  

Changed:
  U   zope.formlib/trunk/CHANGES.txt
  U   zope.formlib/trunk/setup.py
  U   zope.formlib/trunk/src/zope/formlib/form.py
  U   zope.formlib/trunk/src/zope/formlib/form.txt

-=-
Modified: zope.formlib/trunk/CHANGES.txt
===================================================================
--- zope.formlib/trunk/CHANGES.txt	2007-11-09 16:44:29 UTC (rev 81648)
+++ zope.formlib/trunk/CHANGES.txt	2007-11-09 19:03:22 UTC (rev 81649)
@@ -2,11 +2,18 @@
 Changes
 =======
 
-3.4.1 (unreleased)
+3.5.0 (unreleased)
 ==================
 
-...
+* Introduced ``zope.formlib.form.applyData`` which works like
+  ``applyChanges`` but returns a dictionary with information about
+  which attribute of which schema changed.  This information is then
+  sent along with the ``IObjectModifiedEvent``.
 
+  This fixes https://bugs.launchpad.net/zope3/+bug/98483.
+
+* ...
+
 3.4.0 (2007-09-28)
 ==================
 

Modified: zope.formlib/trunk/setup.py
===================================================================
--- zope.formlib/trunk/setup.py	2007-11-09 16:44:29 UTC (rev 81648)
+++ zope.formlib/trunk/setup.py	2007-11-09 19:03:22 UTC (rev 81649)
@@ -22,7 +22,7 @@
     return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
 
 setup(name='zope.formlib',
-      version = '3.4.1dev',
+      version = '3.5.0dev',
       url='http://pypi.python.org/pypi/zope.formlib',
       license='ZPL 2.1',
       description='Form generation and validation library for Zope',

Modified: zope.formlib/trunk/src/zope/formlib/form.py
===================================================================
--- zope.formlib/trunk/src/zope/formlib/form.py	2007-11-09 16:44:29 UTC (rev 81648)
+++ zope.formlib/trunk/src/zope/formlib/form.py	2007-11-09 19:03:22 UTC (rev 81649)
@@ -31,8 +31,8 @@
 from zope.interface.interface import InterfaceClass
 from zope.schema.interfaces import IField
 from zope.schema.interfaces import ValidationError
-import zope.security
 from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
+from zope.lifecycleevent import Attributes
 
 import zope.app.container.interfaces
 import zope.app.form.browser.interfaces
@@ -507,11 +507,11 @@
 
     return [error for error in errors if not isinstance(error, NoInputData)]
 
-def applyChanges(context, form_fields, data, adapters=None):
+def applyData(context, form_fields, data, adapters=None):
     if adapters is None:
         adapters = {}
 
-    changed = False
+    descriptions = {}
 
     for form_field in form_fields:
         field = form_field.field
@@ -528,10 +528,13 @@
         name = form_field.__name__
         newvalue = data.get(name, form_field) # using form_field as marker
         if (newvalue is not form_field) and (field.get(adapter) != newvalue):
-            changed = True
+            descriptions.setdefault(interface, []).append(field.__name__)
             field.set(adapter, newvalue)
 
-    return changed
+    return descriptions
+    
+def applyChanges(context, form_fields, data, adapters=None):
+    return bool(applyData(context, form_fields, data, adapters))
 
 _identifier = re.compile('[A-Za-z][a-zA-Z0-9_]*$')
 
@@ -808,8 +811,12 @@
 
     @action(_("Apply"), condition=haveInputWidgets)
     def handle_edit_action(self, action, data):
-        if applyChanges(self.context, self.form_fields, data, self.adapters):
-            zope.event.notify(ObjectModifiedEvent(self.context))
+        descriptions = applyData(self.context, self.form_fields, data,
+                                self.adapters)
+        if descriptions:
+            descriptions = [Attributes(interface, *tuple(keys))
+                           for interface, keys in descriptions.items()]
+            zope.event.notify(ObjectModifiedEvent(self.context, *descriptions))
             formatter = self.request.locale.dates.getFormatter(
                 'dateTime', 'medium')
 

Modified: zope.formlib/trunk/src/zope/formlib/form.txt
===================================================================
--- zope.formlib/trunk/src/zope/formlib/form.txt	2007-11-09 16:44:29 UTC (rev 81648)
+++ zope.formlib/trunk/src/zope/formlib/form.txt	2007-11-09 19:03:22 UTC (rev 81649)
@@ -1802,3 +1802,38 @@
 
   >>> form.applyChanges(blah, form_fields, {'title': 'new'})
   True
+
+
+Event descriptions
+------------------
+
+The ObjectModifiedEvent can be annotated with descriptions about the involved
+schemas and fields. The formlib provides these annotations with the help of the
+applyData function, which returns a list of modification descriptions:
+
+    >>> form.applyData(blah, form_fields, {'title': 'modified'})
+    {<InterfaceClass __builtin__.IFooBar>: ['title']}
+
+The events are annotated with these descriptions. We need a subscriber to log these
+infos:
+
+    >>> def eventLog(event):
+    ...     desc = event.descriptions[0]
+    ...     print 'Modified:', desc.interface.__identifier__, desc.attributes
+    >>> zope.event.subscribers.append(eventLog)
+
+
+    >>> class MyForm(form.EditForm):
+    ...     form_fields = form.FormFields(IFooBar)
+
+    >>> request = TestRequest()
+    >>> request.form['form.title'] = u'again modified'
+    >>> request.form['form.actions.apply'] = u''
+    >>> MyForm(FooBar(), request)()
+    Modified: __builtin__.IFooBar ('title',)
+    ...
+
+Cleanup:
+
+    >>> zope.event.subscribers.remove(eventLog)
+    



More information about the Zope3-Checkins mailing list