[Zope-dev] z3c.form: TextLineConverter and IFromUnicode
Martin Aspeli
optilude+lists at gmail.com
Thu Mar 12 00:36:51 EDT 2009
Martin Aspeli wrote:
> Hi,
>
> Sorry for doing this by email rather than unit test, but I'm a bit
> over-stretched at the moment.
>
> plone.z3cform has a backport of z3c.form trunk's TextLines widget
> (when's that release coming, any ideas?).
>
> In using it, I discovered that the converter (converter.py on z3c.form
> trunk) does this:
>
> def toFieldValue(self, value):
> """See interfaces.IDataConverter"""
> widget = self.widget
> collectionType = self.field._type
> if isinstance(collectionType, tuple):
> collectionType = collectionType[-1]
> if not len(value):
> return self.field.missing_value
> valueType = self.field.value_type._type
> if isinstance(valueType, tuple):
> valueType = valueType[0]
> return collectionType(valueType(v) for v in value.split())
>
> I was just wondering: should we not try to use IFromUnicode when
> converting the value type? This would be safer, and probably allow us to
> support more value_types. Arguably, we should *require* that the
> value_type for this widget provides IFromUnicode, but we could have the
> fallback _type cast like this.
>
> A simple implementation would be:
>
> def toFieldValue(self, value):
> """See interfaces.IDataConverter"""
> widget = self.widget
> collectionType = self.field._type
> if isinstance(collectionType, tuple):
> collectionType = collectionType[-1]
> if not len(value):
> return self.field.missing_value
>
> value_type = self.field.value_type
> cast = None
> fromUnicode = IFromUnicode(value_type, None)
> if fromUnicode is not None:
> cast = fromUnicode.fromUnicode
> else:
> cast = value_type._type
> if isinstance(cast, (tuple,list)):
> cast = cast[0]
> return collectionType(cast(v) for v in value.split())
And another thing... Would it make sense to always return a sorted list
for sets? Something like:
class TextLinesSetConverter(TextLinesConverter):
zope.component.adapts(
zope.schema.interfaces.ISet, ITextLinesWidget)
def toWidgetValue(self, value):
if value is self.field.missing_value:
return u''
return u'\n'.join(unicode(v) for v in sorted(value))
class TextLinesFrozenSetConverter(TextLinesConverter):
zope.component.adapts(
zope.schema.interfaces.IFrozenSet, ITextLinesWidget)
def toWidgetValue(self, value):
if value is self.field.missing_value:
return u''
return u'\n'.join(unicode(v) for v in sorted(value))
It's confusing to users when the widget renders the value in seemingly
random order. :)
Martin
--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book
More information about the Zope-Dev
mailing list