[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