diff --git a/news/125.feature b/news/125.feature new file mode 100644 index 00000000..3e6515c5 --- /dev/null +++ b/news/125.feature @@ -0,0 +1 @@ +Add support for more widget options when working with relation fields. \ No newline at end of file diff --git a/plone/app/z3cform/configure.zcml b/plone/app/z3cform/configure.zcml index cdd09148..cb089e5b 100644 --- a/plone/app/z3cform/configure.zcml +++ b/plone/app/z3cform/configure.zcml @@ -84,7 +84,13 @@ + + + + diff --git a/plone/app/z3cform/converters.py b/plone/app/z3cform/converters.py index 6c52101d..fae8cb7f 100644 --- a/plone/app/z3cform/converters.py +++ b/plone/app/z3cform/converters.py @@ -17,7 +17,8 @@ from z3c.form.converter import BaseDataConverter from z3c.form.converter import CollectionSequenceDataConverter from z3c.form.converter import SequenceDataConverter -from z3c.relationfield.interfaces import IRelationChoice +from z3c.form.interfaces import ISequenceWidget +from z3c.relationfield.interfaces import IRelation from z3c.relationfield.interfaces import IRelationList from zope.component import adapter from zope.component.hooks import getSite @@ -224,7 +225,7 @@ def toFieldValue(self, value): return collectionType(untokenized_value) -@adapter(IRelationChoice, IRelatedItemsWidget) +@adapter(IRelation, IRelatedItemsWidget) class RelationChoiceRelatedItemsWidgetConverter(BaseDataConverter): """Data converter for RelationChoice fields using the RelatedItemsWidget. """ @@ -249,6 +250,19 @@ def toFieldValue(self, value): return self.field.missing_value +@adapter(IRelation, ISequenceWidget) +class RelationChoiceSelectWidgetConverter(RelationChoiceRelatedItemsWidgetConverter): + """Data converter for RelationChoice fields using with SequenceWidgets, + which expect sequence values. + """ + + def toWidgetValue(self, value): + if not value: + missing = self.field.missing_value + return [] if missing is None else missing + return [IUUID(value)] + + @adapter(ICollection, IRelatedItemsWidget) class RelatedItemsDataConverter(BaseDataConverter): """Data converter for ICollection fields using the RelatedItemsWidget.""" @@ -287,7 +301,9 @@ def toFieldValue(self, value): collectionType = collectionType[-1] separator = getattr(self.widget, 'separator', ';') - value = value.split(separator) + # Some widgets (like checkbox) return lists + if isinstance(value, six.string_types): + value = value.split(separator) if IRelationList.providedBy(self.field): try: @@ -311,6 +327,30 @@ def toFieldValue(self, value): return collectionType(valueType(v) for v in value) +@adapter(IRelationList, ISequenceWidget) +class RelationListSelectWidgetDataConverter(RelatedItemsDataConverter): + """Data converter for RelationChoice fields using with SequenceWidgets, + which expect sequence values. + """ + + def toWidgetValue(self, value): + """Converts from field value to widget. + + :param value: List of catalog brains. + :type value: list + + :returns: List of of UID. + :rtype: list + """ + if not value: + missing = self.field.missing_value + return [] if missing is None else missing + if IRelationList.providedBy(self.field): + return [IUUID(o) for o in value if o] + else: + return [v for v in value if v] + + @adapter(IList, IQueryStringWidget) class QueryStringDataConverter(BaseDataConverter): """Data converter for IList.""" diff --git a/plone/app/z3cform/widget.py b/plone/app/z3cform/widget.py index b15fd2e6..26384c79 100644 --- a/plone/app/z3cform/widget.py +++ b/plone/app/z3cform/widget.py @@ -391,13 +391,14 @@ def _view_context(self): return view_context def get_vocabulary(self): - if self.vocabulary: + if self.vocabulary and isinstance(self.vocabulary, six.text_type): factory = queryUtility( IVocabularyFactory, self.vocabulary, ) if factory: return factory(self._view_context()) + return self.vocabulary def display_items(self): if self.value: