[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