[Checkins] SVN: z3c.form/trunk/ - Feature: The `TypeError` message used when a field does not provide
Stephan Richter
srichter at cosmos.phy.tufts.edu
Sun Aug 31 01:05:16 EDT 2008
Log message for revision 90625:
- Feature: The `TypeError` message used when a field does not provide
``IFormUnicode`` now also contains the type of the field.
- Reviewed Roger's latest features and improved test wording.
Changed:
U z3c.form/trunk/CHANGES.txt
U z3c.form/trunk/src/z3c/form/browser/multi.py
U z3c.form/trunk/src/z3c/form/browser/multi.txt
U z3c.form/trunk/src/z3c/form/converter.py
U z3c.form/trunk/src/z3c/form/converter.txt
-=-
Modified: z3c.form/trunk/CHANGES.txt
===================================================================
--- z3c.form/trunk/CHANGES.txt 2008-08-30 23:41:39 UTC (rev 90624)
+++ z3c.form/trunk/CHANGES.txt 2008-08-31 05:05:13 UTC (rev 90625)
@@ -2,23 +2,24 @@
CHANGES
=======
-Version 1.9.1dev (unreleased)
------------------------------
+Version 2.0.0 (2008-??-??)
+--------------------------
-- Feature: Implemented MultiWidget. The MultiWidget allows to use simple fields
- like ITextLine, IInt, IPassword, etc. in a IList or ITuple sequence. Since we
- used the term sequence for the sequence we can choose from, from the point of
- view of a widget e.g. a source or vocabulary, the name multi is used for the
- widget which allows to collect values for a sequence field.
+- Feature: The `TypeError` message used when a field does not provide
+ ``IFormUnicode`` now also contains the type of the field.
-- Feature: Implemented TextLinesWidget. This widget offers a TextArea and
- splits lines in sequence items. This is usfull for power user interfaces.
- The widget can be used for e.g. (IList or ITuple) of ITextLine or any other
- (sequence) of simple field like IPassword, IInt etc.
+- Feature: Implemented the `MultiWidget` widget. This widget allows to use
+ simple fields like `ITextLine`, `IInt`, `IPassword`, etc. in a `IList` or
+ `ITuple` sequence.
-- Remove unused imports, adjust buildout dependencies in setup.py
+- Feature: Implemented `TextLinesWidget` widget. This widget offers a text
+ area element and splits lines in sequence items. This is usfull for power
+ user interfaces. The widget can be used for sequence fields (e.g. `IList`)
+ that specify a simple value type field (e.g. `ITextLine` or `IInt`).
+- Bug: Remove unused imports, adjust buildout dependencies in `setup.py`.
+
Version 1.9.0 (2008-08-26)
--------------------------
Modified: z3c.form/trunk/src/z3c/form/browser/multi.py
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/multi.py 2008-08-30 23:41:39 UTC (rev 90624)
+++ z3c.form/trunk/src/z3c/form/browser/multi.py 2008-08-31 05:05:13 UTC (rev 90625)
@@ -67,7 +67,8 @@
name = '%s.remove' % (widget.name)
if name in self.request:
append(widget.id)
- self.widgets = [widget for widget in self.widgets if widget.id not in ids]
+ self.widgets = [widget for widget in self.widgets
+ if widget.id not in ids]
@zope.interface.implementer(interfaces.IFieldWidget)
def multiFieldWidgetFactory(field, request):
Modified: z3c.form/trunk/src/z3c/form/browser/multi.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/multi.txt 2008-08-30 23:41:39 UTC (rev 90624)
+++ z3c.form/trunk/src/z3c/form/browser/multi.txt 2008-08-31 05:05:13 UTC (rev 90625)
@@ -37,8 +37,7 @@
... (None, None, None, None, interfaces.IMultiWidget),
... IPageTemplate, name=interfaces.INPUT_MODE)
-For the next test, we need to setup our button handler adapters. If we render
-the widget we get an emtpy widget:
+For the next test, we need to setup our button handler adapters.
>>> from z3c.form import button
>>> zope.component.provideAdapter(button.ButtonActions)
@@ -46,13 +45,15 @@
>>> zope.component.provideAdapter(button.ButtonAction,
... provides=interfaces.IButtonAction)
-And our submit buttons will need some template:
+Our submit buttons will need a template as well:
>>> zope.component.provideAdapter(
... WidgetTemplateFactory(getPath('submit_input.pt'), 'text/html'),
... (None, None, None, None, interfaces.ISubmitWidget),
... IPageTemplate, name=interfaces.INPUT_MODE)
+We can now render the widget:
+
>>> widget.update()
>>> print widget.render()
<div class="multi-widget">
@@ -67,9 +68,9 @@
</div>
<input type="hidden" name="widget.name.count" value="0" />
-As you can see the widget is empty and doesn't provide values. Let's
-update the widget and check it again. But first register a IFieldWidget adapter
-and a template for our IInt field:
+As you can see the widget is empty and doesn't provide values. This is because
+the widget does not know what sub-widgets to display. So let's register a
+`IFieldWidget` adapter and a template for our `IInt` field:
>>> import z3c.form.interfaces
>>> from z3c.form.browser.text import TextFieldWidget
@@ -81,6 +82,8 @@
... (None, None, None, None, interfaces.ITextWidget),
... IPageTemplate, name=interfaces.INPUT_MODE)
+Let's now update the widget and check it again.
+
>>> widget.update()
>>> print widget.render()
<div class="multi-widget">
@@ -96,7 +99,7 @@
<input type="hidden" name="widget.name.count" value="0" />
It's still the same. Since the widget doesn't provide a field nothing useful
-get rendered. Now let's define a fiel for this widget and check it again:
+gets rendered. Now let's define a field for this widget and check it again:
>>> field = zope.schema.List(
... __name__=u'foo',
@@ -117,8 +120,8 @@
</div>
<input type="hidden" name="widget.name.count" value="0" />
-As you can see, there is still no input value. Let's provide some values for
-this widget. Before we can do that, we will need to register a data converter
+As you can see, there is still no input value. Let's provide some values for
+this widget. Before we can do that, we will need to register a data converter
for our multi widget and the data converter dispatcher adapter:
>>> from z3c.form.converter import IntegerDataConverter
@@ -146,7 +149,8 @@
id="widget-id-0-remove"
name="widget.name.0.remove" />
</div>
- <div class="multi-widget-input"><input type="text" id="widget-id-0" name="widget.name.0"
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-0" name="widget.name.0"
class="text-widget required int-field" value="42" />
</div>
</div>
@@ -165,7 +169,8 @@
id="widget-id-1-remove"
name="widget.name.1.remove" />
</div>
- <div class="multi-widget-input"><input type="text" id="widget-id-1" name="widget.name.1"
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-1" name="widget.name.1"
class="text-widget required int-field" value="43" />
</div>
</div>
@@ -181,8 +186,8 @@
</div>
<input type="hidden" name="widget.name.count" value="2" />
-If we now oush the ``Add`` button, we will get a new input field for enter a
-new value:
+If we now click on the ``Add`` button, we will get a new input field for enter
+a new value:
>>> widget.request = TestRequest(form={'widget.name.count':u'2',
... 'widget.name.0':u'42',
@@ -205,7 +210,8 @@
id="widget-id-0-remove"
name="widget.name.0.remove" />
</div>
- <div class="multi-widget-input"><input type="text" id="widget-id-0" name="widget.name.0"
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-0" name="widget.name.0"
class="text-widget required int-field" value="42" />
</div>
</div>
@@ -224,7 +230,8 @@
id="widget-id-1-remove"
name="widget.name.1.remove" />
</div>
- <div class="multi-widget-input"><input type="text" id="widget-id-1" name="widget.name.1"
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-1" name="widget.name.1"
class="text-widget required int-field" value="43" />
</div>
</div>
@@ -243,7 +250,8 @@
id="widget-id-2-remove"
name="widget.name.2.remove" />
</div>
- <div class="multi-widget-input"><input type="text" id="widget-id-2" name="widget.name.2"
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-2" name="widget.name.2"
class="text-widget required int-field" value="" />
</div>
</div>
@@ -282,7 +290,8 @@
id="widget-id-0-remove"
name="widget.name.0.remove" />
</div>
- <div class="multi-widget-input"><input type="text" id="widget-id-0" name="widget.name.0"
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-0" name="widget.name.0"
class="text-widget required int-field" value="42" />
</div>
</div>
@@ -301,7 +310,8 @@
id="widget-id-1-remove"
name="widget.name.1.remove" />
</div>
- <div class="multi-widget-input"><input type="text" id="widget-id-1" name="widget.name.1"
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-1" name="widget.name.1"
class="text-widget required int-field" value="43" />
</div>
</div>
@@ -320,9 +330,10 @@
id="widget-id-2-remove"
name="widget.name.2.remove" />
</div>
- <div class="multi-widget-input"><input type="text" id="widget-id-2" name="widget.name.2"
- class="text-widget required int-field" value="44" />
- </div>
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-2" name="widget.name.2"
+ class="text-widget required int-field" value="44" />
+ </div>
</div>
</div>
<div class="buttons">
@@ -336,9 +347,9 @@
</div>
<input type="hidden" name="widget.name.count" value="3" />
-As you can see in the above sample, the new stored value get rendered as a
-real value and the new adding value input field is gone. Now let's try
-to remove an existing value:
+As you can see in the above sample, the new stored value gest rendered as a
+real value and the new adding value input field is gone. Now let's try to
+remove an existing value:
>>> widget.request = TestRequest(form={'widget.name.count':u'3',
... 'widget.name.0':u'42',
@@ -363,7 +374,8 @@
id="widget-id-0-remove"
name="widget.name.0.remove" />
</div>
- <div class="multi-widget-input"><input type="text" id="widget-id-0" name="widget.name.0"
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-0" name="widget.name.0"
class="text-widget required int-field" value="42" />
</div>
</div>
@@ -382,7 +394,8 @@
id="widget-id-2-remove"
name="widget.name.2.remove" />
</div>
- <div class="multi-widget-input"><input type="text" id="widget-id-2" name="widget.name.2"
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-2" name="widget.name.2"
class="text-widget required int-field" value="44" />
</div>
</div>
@@ -398,11 +411,11 @@
</div>
<input type="hidden" name="widget.name.count" value="2" />
-Show how the error handling works. Let's use a bad none integer value as input
-for our internal (sub) widget.
+Error handling is next. Let's use teh value "bad" (an invlaid integer literal)
+as input for our internal (sub) widget.
>>> from z3c.form.error import ErrorViewSnippet
- >>> from z3c.form.error import StandardErrorViewTemplate
+ >>> from z3c.form.error import StandardErrorViewTemplate
>>> zope.component.provideAdapter(ErrorViewSnippet)
>>> zope.component.provideAdapter(StandardErrorViewTemplate)
@@ -426,7 +439,8 @@
id="widget-id-0-remove"
name="widget.name.0.remove" />
</div>
- <div class="multi-widget-input"><input type="text" id="widget-id-0" name="widget.name.0"
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-0" name="widget.name.0"
class="text-widget required int-field" value="42" />
</div>
</div>
@@ -445,12 +459,14 @@
id="widget-id-1-remove"
name="widget.name.1.remove" />
</div>
- <div class="multi-widget-input"><input type="text" id="widget-id-1" name="widget.name.1"
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-1" name="widget.name.1"
class="text-widget required int-field" value="bad" />
</div>
</div>
<div class="error">
- <div class="error">The entered value is not a valid integer literal.</div>
+ <div class="error">The entered value is not a valid integer
+ literal.</div>
</div>
</div>
<div class="buttons">
@@ -469,9 +485,9 @@
-----
There is an option which allows to disable the label for the (sub) widgets.
-You can set the option showLabel to False which will skip rendering the labels.
-Or of corse you can register your own template for your layer if you like to
-skip the label rendering for all widgets.
+You can set the `showLabel` option to `False` which will skip rendering the
+labels. Alternatively you can also register your own template for your layer
+if you like to skip the label rendering for all widgets.
>>> field = zope.schema.List(
... __name__=u'foo',
@@ -493,7 +509,8 @@
class="multi-widget-checkbox checkbox-widget"
id="None-0-remove" name="None.0.remove" />
</div>
- <div class="multi-widget-input"><input type="text" id="None-0" name="None.0"
+ <div class="multi-widget-input"><input
+ type="text" id="None-0" name="None.0"
class="text-widget required int-field" value="42" />
</div>
</div>
@@ -505,7 +522,8 @@
class="multi-widget-checkbox checkbox-widget"
id="None-1-remove" name="None.1.remove" />
</div>
- <div class="multi-widget-input"><input type="text" id="None-1" name="None.1"
+ <div class="multi-widget-input"><input
+ type="text" id="None-1" name="None.1"
class="text-widget required int-field" value="43" />
</div>
</div>
Modified: z3c.form/trunk/src/z3c/form/converter.py
===================================================================
--- z3c.form/trunk/src/z3c/form/converter.py 2008-08-30 23:41:39 UTC (rev 90624)
+++ z3c.form/trunk/src/z3c/form/converter.py 2008-08-31 05:05:13 UTC (rev 90625)
@@ -63,11 +63,12 @@
def __init__(self, field, widget):
super(FieldDataConverter, self).__init__(field, widget)
if not zope.schema.interfaces.IFromUnicode.providedBy(field):
+ fieldName = ''
if field.__name__:
- raise TypeError('Field ``%s`` must provide ``IFromUnicode``.' \
- % field.__name__)
- else:
- raise TypeError('Field must provide ``IFromUnicode``.')
+ fieldName = '``%s`` ' % field.__name__
+ raise TypeError(
+ 'Field %sof type ``%s`` must provide ``IFromUnicode``.' %(
+ fieldName, type(field).__name__))
@zope.component.adapter(interfaces.IFieldWidget)
Modified: z3c.form/trunk/src/z3c/form/converter.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/converter.txt 2008-08-30 23:41:39 UTC (rev 90624)
+++ z3c.form/trunk/src/z3c/form/converter.txt 2008-08-31 05:05:13 UTC (rev 90625)
@@ -34,16 +34,15 @@
>>> converter.FieldDataConverter(zope.schema.Date(), text)
Traceback (most recent call last):
...
- TypeError: Field must provide ``IFromUnicode``.
+ TypeError: Field of type ``Date`` must provide ``IFromUnicode``.
A named field will tell it's name:
>>> converter.FieldDataConverter(zope.schema.Date(__name__="foobar"), text)
Traceback (most recent call last):
...
- TypeError: Field ``foobar`` must provide ``IFromUnicode``.
+ TypeError: Field ``foobar`` of type ``Date`` must provide ``IFromUnicode``.
-
However, the ``FieldDataConverter`` is registered for ``IField``, since many
fields (like ``Decimal``) for which we want to create custom converters
provide ``IFromUnicode`` more specifically than their characterizing interface
@@ -382,8 +381,8 @@
True
-FileUpload Data Converter
--------------------------
+File Upload Data Converter
+--------------------------
Since the ``Bytes`` field can contain a FileUpload object, we have to make
sure we can convert FileUpload objects to bytes too.
@@ -644,12 +643,12 @@
represent two states by desgin.
-TextLines Data Converter
-------------------------
+Text Lines Data Converter
+-------------------------
-For sequence widgets and fields that work with a sequence of TextLine, a simple
-data converter is required. Let's now create a list of text lines field and a
-widget:
+For sequence widgets and fields that work with a sequence of `TextLine` value
+fields, a simple data converter is required. Let's create a list of text lines
+field and a widget:
>>> languages = zope.schema.List(
... value_type=zope.schema.TextLine(),
@@ -671,7 +670,7 @@
u'de\nfr\nen'
-The result is always a string, since textlines widgets only deal with textarea
+The result is always a string, since text lines widgets only deal with textarea
as input field. Of course, we can convert the widget value back to an internal
value:
More information about the Checkins
mailing list