From aac89c6642739a72b4919c8dfa2a68e99a4197e0 Mon Sep 17 00:00:00 2001 From: Alec Mitchell Date: Sat, 30 Jan 2021 13:58:23 -0800 Subject: [PATCH 1/3] Register converters to allow Select widgets to be used for RelationChoice and RelationList. --- plone/app/z3cform/configure.zcml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plone/app/z3cform/configure.zcml b/plone/app/z3cform/configure.zcml index 7e2d5471..ed6cbdca 100644 --- a/plone/app/z3cform/configure.zcml +++ b/plone/app/z3cform/configure.zcml @@ -174,7 +174,11 @@ + + From 73f28f9b84fd794493f765d9956b70b83eba2d6e Mon Sep 17 00:00:00 2001 From: Alec Mitchell Date: Sat, 30 Jan 2021 17:58:38 -0800 Subject: [PATCH 2/3] Register additional Relation data converters for use with Select, AJAXSelect, and CheckBox widgets, among others. Add support for non-named vocabularies to AJAXSelectWidget. --- plone/app/z3cform/configure.zcml | 10 ++++--- plone/app/z3cform/converters.py | 46 +++++++++++++++++++++++++++++--- plone/app/z3cform/widget.py | 3 ++- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/plone/app/z3cform/configure.zcml b/plone/app/z3cform/configure.zcml index ed6cbdca..f1013258 100644 --- a/plone/app/z3cform/configure.zcml +++ b/plone/app/z3cform/configure.zcml @@ -174,11 +174,13 @@ - - + for="z3c.relationfield.interfaces.IRelationChoice .interfaces.ITextWidget" /> + + + + diff --git a/plone/app/z3cform/converters.py b/plone/app/z3cform/converters.py index c74a93e5..10f7765e 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 18d1bdd8..97b7efe0 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: From 055daf9680fc3652249db2d41022bb0aad2d51aa Mon Sep 17 00:00:00 2001 From: Alec Mitchell Date: Sun, 28 Feb 2021 20:05:19 -0800 Subject: [PATCH 3/3] Add changelog entry. --- news/125.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/125.feature 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