[Checkins] SVN: grok/trunk/src/grok/ Fix a backwards compatibility issue with the form refactoring:

Philipp von Weitershausen philikon at philikon.de
Fri Mar 16 13:55:28 EDT 2007


Log message for revision 73224:
  Fix a backwards compatibility issue with the form refactoring:
  
  * It should *not* be allowed to override a form's render() method. Bring back the
    tests for that.
  
  * It *should* be possible to provide an update() method on the form. It will be
    called before any of the form processing or rendering happens. Test this.
  
  This involves "renaming" the update() method from the FormBase base class to update_form()
  so that the update() method is free for subclasses to override.
  

Changed:
  U   grok/trunk/src/grok/components.py
  A   grok/trunk/src/grok/ftests/form/update.py
  U   grok/trunk/src/grok/meta.py
  A   grok/trunk/src/grok/tests/form/norender.py
  A   grok/trunk/src/grok/tests/form/norender2.py

-=-
Modified: grok/trunk/src/grok/components.py
===================================================================
--- grok/trunk/src/grok/components.py	2007-03-16 16:22:04 UTC (rev 73223)
+++ grok/trunk/src/grok/components.py	2007-03-16 17:55:28 UTC (rev 73224)
@@ -359,7 +359,18 @@
     """Mix-in to console zope.formlib's forms with grok.View and to
     add some more useful methods."""
 
+    def update(self):
+        """Subclasses can override this method just like on regular
+        grok.Views. It will be called before any form processing
+        happens."""
+
+    def update_form(self):
+        """Update the form, meaning, process form input using widgets."""
+        super(GrokForm, self).update()
+
     def render(self):
+        """Render the form, either using the form templates or
+        whatever the actions returned in form_result."""
         # if the form has been updated, it will already have a result
         if self.form_result is None:
             if self.form_reset:
@@ -371,6 +382,16 @@
 
         return self.form_result
 
+    # Mark the render() method as a method from the base class. That
+    # way we can detect whether somebody overrides render() in a
+    # subclass (which we don't allow).
+    render.base_method = True
+
+    def __call__(self):
+        self.update()
+        self.update_form()
+        return self.render() 
+
     def apply_changes(self, obj, **data):
         if form.applyChanges(obj, self.form_fields, data, self.adapters):
             event.notify(ObjectModifiedEvent(obj))

Added: grok/trunk/src/grok/ftests/form/update.py
===================================================================
--- grok/trunk/src/grok/ftests/form/update.py	2007-03-16 16:22:04 UTC (rev 73223)
+++ grok/trunk/src/grok/ftests/form/update.py	2007-03-16 17:55:28 UTC (rev 73224)
@@ -0,0 +1,38 @@
+"""
+Forms can implement an update() method that will be called before any
+form processing has happened:
+
+  >>> import grok
+  >>> grok.grok('grok.ftests.form.update')
+  >>> from grok.ftests.form.update import Mammoth
+  >>> getRootFolder()["manfred"] = Mammoth()
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> browser = Browser()
+  >>> browser.handleErrors = False
+  >>> browser.open("http://localhost/manfred/edit")
+  >>> browser.getControl(name="form.name").value = "Ellie"
+  >>> browser.getControl("Apply").click()
+
+  >>> browser.open("http://localhost/manfred")
+  >>> print browser.contents
+  Ellie, the Mammoth reports: The form's update() was called and my name was Manfred.
+"""
+import grok
+from zope import schema
+
+class Mammoth(grok.Model):
+    class fields:
+        name = schema.TextLine(title=u"Name", default=u'Manfred')
+
+class Index(grok.View):
+
+    def render(self):
+        return "%s, the Mammoth reports: %s" % (self.context.name,
+                                                self.context.report)
+
+class Edit(grok.EditForm):
+
+    def update(self):
+        self.context.report = ("The form's update() was called and my name "
+                               "was %s." % self.context.name)


Property changes on: grok/trunk/src/grok/ftests/form/update.py
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: grok/trunk/src/grok/meta.py
===================================================================
--- grok/trunk/src/grok/meta.py	2007-03-16 16:22:04 UTC (rev 73223)
+++ grok/trunk/src/grok/meta.py	2007-03-16 17:55:28 UTC (rev 73224)
@@ -132,6 +132,13 @@
             if getattr(factory, 'form_fields', None) is None:
                 factory.form_fields = formlib.get_auto_fields(view_context)
 
+            if not getattr(factory.render, 'base_method', False):
+                raise GrokError(
+                    "It is not allowed to specify a custom 'render' "
+                    "method for form %r. Forms either use the default "
+                    "template or a custom-supplied one." % factory,
+                    factory)
+
         # find templates
         template_name = util.class_annotation(factory, 'grok.template',
                                               factory_name)

Copied: grok/trunk/src/grok/tests/form/norender.py (from rev 73208, grok/trunk/src/grok/tests/form/norender.py)

Copied: grok/trunk/src/grok/tests/form/norender2.py (from rev 73208, grok/trunk/src/grok/tests/form/norender2.py)



More information about the Checkins mailing list