[Zope3-checkins] SVN: Zope3/branches/3.2/ backported missing zope.formlib bugfixes from trunk (r40546:68015):

Yvo Schubbe y.2006_ at wcm-solutions.de
Thu Sep 28 14:26:33 EDT 2006


Log message for revision 70426:
  backported missing zope.formlib bugfixes from trunk (r40546:68015):
  
  r40608, r41043, r41119, part of r41757, r67264, r67278, r67279, r67774

Changed:
  U   Zope3/branches/3.2/doc/CHANGES.txt
  U   Zope3/branches/3.2/src/zope/formlib/form.py
  U   Zope3/branches/3.2/src/zope/formlib/form.txt
  U   Zope3/branches/3.2/src/zope/formlib/pageform.pt
  U   Zope3/branches/3.2/src/zope/formlib/tests.py

-=-
Modified: Zope3/branches/3.2/doc/CHANGES.txt
===================================================================
--- Zope3/branches/3.2/doc/CHANGES.txt	2006-09-28 15:56:27 UTC (rev 70425)
+++ Zope3/branches/3.2/doc/CHANGES.txt	2006-09-28 18:26:32 UTC (rev 70426)
@@ -10,6 +10,11 @@
 
     Bug fixes
 
+      - Fixed error handling in sequence item input widget. This widget
+        was raising a ValidationError instead a WidgetInputError. The formlib
+        didn't catch ValidationErrors. Added also ValidationError handling to
+        the formlib as a fallback for broken widget implementations.
+
       - Fixed issue 696: No display widget was registered for ISet fields with
         a IChoice(IBaseVocabulary) value type.
 

Modified: Zope3/branches/3.2/src/zope/formlib/form.py
===================================================================
--- Zope3/branches/3.2/src/zope/formlib/form.py	2006-09-28 15:56:27 UTC (rev 70425)
+++ Zope3/branches/3.2/src/zope/formlib/form.py	2006-09-28 18:26:32 UTC (rev 70426)
@@ -30,6 +30,7 @@
 from zope.interface.interface import InterfaceClass
 import zope.interface.interfaces
 from zope.schema.interfaces import IField
+from zope.schema.interfaces import ValidationError
 import zope.security
 
 import zope.app.container.interfaces
@@ -37,7 +38,7 @@
 import zope.app.form.browser.interfaces
 from zope.app.form.interfaces import IInputWidget, IDisplayWidget
 from zope.app.form.interfaces import WidgetsError, MissingInputError
-from zope.app.form.interfaces import InputErrors
+from zope.app.form.interfaces import InputErrors, WidgetInputError
 from zope.app.pagetemplate import ViewPageTemplateFile
 from zope.app.publisher.browser import BrowserView
 
@@ -316,6 +317,10 @@
 
             try:
                 data[name] = widget.getInputValue()
+            except ValidationError, error:
+                # convert field ValidationError to WidgetInputError
+                error = WidgetInputError(widget.name, widget.label, error)
+                errors.append(error)
             except InputErrors, error:
                 errors.append(error)
 
@@ -753,6 +758,8 @@
                     zope.app.form.browser.interfaces.IWidgetInputErrorView)
                 title = getattr(error, 'widget_title', None) # duck typing
                 if title:
+                    if isinstance(title, zope.i18n.Message):
+                        title = zope.i18n.translate(title, context=self.request)
                     yield '%s: %s' % (title, view.snippet())
                 else:
                     yield view.snippet()

Modified: Zope3/branches/3.2/src/zope/formlib/form.txt
===================================================================
--- Zope3/branches/3.2/src/zope/formlib/form.txt	2006-09-28 15:56:27 UTC (rev 70425)
+++ Zope3/branches/3.2/src/zope/formlib/form.txt	2006-09-28 18:26:32 UTC (rev 70426)
@@ -12,15 +12,15 @@
 templates in practice.
 
 This document starts with low-level APIs.  We eventually build up to
-higherlevel APIs that allow forms to be defined with just a little bit
-of meta data.  Impatiant readers may wish to skip to the later
+higher-level APIs that allow forms to be defined with just a little bit
+of meta data.  Impatient readers may wish to skip to the later
 sections, especially the section on `Helpful base classes`_. :)
 
 A form class can define ordered collections of "form fields" using
 the `Fields` constructor. Form fields are distinct from and build on
 schema fields.  A schema field specified attribute values.  Form
 fields specify how a schema field should be used in a form.  The
-simplest way to define a collection onf form fields is by passing a
+simplest way to define a collection of form fields is by passing a
 schema to the `Fields` constructor:
 
     >>> from zope import interface, schema
@@ -53,7 +53,7 @@
     >>> [w.__name__ for w in MyForm.form_fields.select('name', 'identifier')]
     ['name', 'identifier']
 
-or by omiting fields:
+or by omitting fields:
 
     >>> [w.__name__ for w in MyForm.form_fields.omit('now', 'identifier')]
     ['name', 'min_size', 'max_size']
@@ -86,8 +86,8 @@
     ...             ignore_request=ignore_request)
     ...         return '\n'.join([w() for w in widgets])
 
-Here we used form.setUpWidgets to create widget instances from our
-form-field specifications.  The second argument to `setUpWidgets` is a
+Here we used ``form.setUpWidgets`` to create widget instances from our
+form-field specifications.  The second argument to ``setUpWidgets`` is a
 form prefix.  All of the widgets on this form are given the same
 prefix.  This allows multiple forms to be used within a single form
 tag, assuming that each form uses a different form prefix.
@@ -654,7 +654,7 @@
   - `status` is a string that, if set, is displayed at the top of the
     form.
 
-  - `errors` is the set of errors found when valiadting.
+  - `errors` is the set of errors found when validating.
 
   - `widgets` is a list of set-up widgets
 
@@ -850,7 +850,7 @@
 Helpful base classes
 ====================
 
-Our form has a lot of repetative code. A number of helpful base
+Our form has a lot of repetitive code. A number of helpful base
 classes provide standard form implementation.
 
 Form
@@ -869,7 +869,7 @@
   To render the form
 
 `template`
-  A default template.  Note that this a NamedTemplate named "default",
+  A default template.  Note that this is a NamedTemplate named "default",
   so the template may also be overridden by registering an alternate
   default template.
 
@@ -932,7 +932,7 @@
 
 We also used the `action` decorator.  The action decorator:
 
-- creates an `actions` variable if one isn't aleady created,
+- creates an `actions` variable if one isn't already created,
 
 - defines an action with the given label and any other arguments, and
 
@@ -997,7 +997,7 @@
 Our `handle_edit_action` action is common to edit forms.  An
 `EditForm` base class captures this commonality.  It also sets up
 widget widgets a bit differently.  The `EditForm` base class sets up
-widgets as if the form fields had been set up with the render_context`
+widgets as if the form fields had been set up with the `render_context`
 option.
 
     >>> class MyForm(form.EditForm):
@@ -1207,7 +1207,7 @@
 ========================
 
 The form-field constructor is very flexible.  We've already seen that
-we can sppply multiple schemas.  Here are some other things you can
+we can supply multiple schemas.  Here are some other things you can
 do.
 
 Specifying individual fields
@@ -1245,11 +1245,11 @@
 
 But make sure the fields have a '__name__', as was done above.
 
-Concatinating field collections
+Concatenating field collections
 -------------------------------
 
 It is sometimes convenient to combine multiple field collections.
-Field collections support concatination. For example, we may want to
+Field collections support concatenation. For example, we may want to
 combine field definitions:
 
     >>> class MyExpandedForm(form.Form):
@@ -1312,7 +1312,7 @@
 ----------------------
 
 We may want to indicate that some fields should be used for input even
-if the underlying schema field is readonly. We can do this using the
+if the underlying schema field is read-only. We can do this using the
 `for_input` option when setting up form_fields:
 
     >>> class MyForm(form.Form):

Modified: Zope3/branches/3.2/src/zope/formlib/pageform.pt
===================================================================
--- Zope3/branches/3.2/src/zope/formlib/pageform.pt	2006-09-28 15:56:27 UTC (rev 70425)
+++ Zope3/branches/3.2/src/zope/formlib/pageform.pt	2006-09-28 18:26:32 UTC (rev 70426)
@@ -29,7 +29,7 @@
         e.style.visibility = viz;
       }
     }
-    var help = document.getElementById("field-help-for-" + field.name);
+    var help = document.getElementById("field-help-for-" + ob.htmlFor);
     if (help) {
       help.style.visibility = state && 'visible' || 'hidden';
     }

Modified: Zope3/branches/3.2/src/zope/formlib/tests.py
===================================================================
--- Zope3/branches/3.2/src/zope/formlib/tests.py	2006-09-28 15:56:27 UTC (rev 70425)
+++ Zope3/branches/3.2/src/zope/formlib/tests.py	2006-09-28 18:26:32 UTC (rev 70426)
@@ -226,6 +226,87 @@
 
 """
 
+
+def test_error_views_i18n():
+    """\
+
+    >>> from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
+    >>> from zope.i18n.interfaces import ITranslationDomain
+    >>> messageDic = {('ja', u'Summary'): u'MatomeYaken'}
+    >>> sd = SimpleTranslationDomain('KansaiBen.domain', messageDic)
+    >>> component.provideUtility(provides=ITranslationDomain,
+    ...                          component=sd,
+    ...                          name='KansaiBen.domain')
+    >>> from zope.i18n.negotiator import negotiator
+    >>> component.provideUtility(negotiator)
+    >>> _ = zope.i18nmessageid.MessageFactory('KansaiBen.domain')
+    >>> myError = zope.app.form.interfaces.WidgetInputError(
+    ...     field_name='summary',
+    ...     widget_title=_(u'Summary'))
+    >>> from zope.publisher.browser import TestRequest
+    >>> req = TestRequest()
+    >>> req._environ['HTTP_ACCEPT_LANGUAGE'] = 'ja; q=1.0'
+    >>> mybase = form.FormBase(None, req)
+    >>> mybase.errors = (myError,)
+    >>> save = mybase.error_views()
+    >>> save.next()
+    u'MatomeYaken: <span class="error"></span>'
+    
+"""
+
+
+def test_error_handling():
+    """\
+
+Let's test the getWidgetsData method which is responsible for handling widget
+erros raised by the widgets getInputValue method.
+
+    >>> from zope.interface import implements
+    >>> from zope.app.form.interfaces import IInputWidget
+    >>> class Widget(object):
+    ...     implements(IInputWidget)
+    ...     def __init__(self):
+    ...         self.name = 'form.summary'
+    ...         self.label = 'Summary'
+    ...     def hasInput(self):
+    ...         return True
+    ...     def getInputValue(self):
+    ...         raise zope.app.form.interfaces.WidgetInputError(
+    ...         field_name='summary',
+    ...         widget_title=u'Summary')
+    >>> widget = Widget()
+    >>> inputs = [(True, widget)]
+    >>> widgets = form.Widgets(inputs, 5)
+    >>> errors = form.getWidgetsData(widgets, 'form', {'summary':'value'})
+    >>> errors #doctest: +ELLIPSIS
+    [<zope.app.form.interfaces.WidgetInputError instance at ...>]
+
+Let's see what happens if a widget doesn't convert a ValidationError 
+raised by a field to a WidgetInputError. This should not happen if a widget 
+converts ValidationErrors to WidgetInputErrors. But since I just fixed 
+yesterday the sequence input widget, I decided to catch ValidationError also
+in the formlib as a fallback if some widget doen't handle errors correct. (ri)
+
+    >>> from zope.schema.interfaces import ValidationError
+    >>> class Widget(object):
+    ...     implements(IInputWidget)
+    ...     def __init__(self):
+    ...         self.name = 'form.summary'
+    ...         self.label = 'summary'
+    ...     def hasInput(self):
+    ...         return True
+    ...     def getInputValue(self):
+    ...         raise ValidationError('A error message')
+    >>> widget = Widget()
+    >>> inputs = [(True, widget)]
+    >>> widgets = form.Widgets(inputs, 5)
+    >>> errors = form.getWidgetsData(widgets, 'form', {'summary':'value'})
+    >>> errors #doctest: +ELLIPSIS
+    [<zope.app.form.interfaces.WidgetInputError instance at ...>]
+    
+"""
+
+
 def test_form_template_i18n():
     """\
 Let's try to check that the formlib templates handle i18n correctly.



More information about the Zope3-Checkins mailing list