Skip to content

Commit

Permalink
Register additional Relation data converters for use with Select, AJA…
Browse files Browse the repository at this point in the history
…XSelect, and CheckBox widgets, among others. Add support for non-named vocabularies to AJAXSelectWidget.
  • Loading branch information
alecpm committed Jan 31, 2021
1 parent aac89c6 commit 73f28f9
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 8 deletions.
10 changes: 6 additions & 4 deletions plone/app/z3cform/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,13 @@
<adapter factory=".converters.AjaxSelectWidgetConverter" />
<adapter factory=".converters.QueryStringDataConverter" />
<adapter factory=".converters.RelationChoiceRelatedItemsWidgetConverter" />
<adapter factory=".converters.RelatedItemsDataConverter"
for="z3c.relationfield.interfaces.IRelationList .interfaces.ISelectWidget"/>
<adapter factory=".converters.RelatedItemsDataConverter" />
<adapter factory=".converters.RelationChoiceRelatedItemsWidgetConverter"
for="z3c.relationfield.interfaces.IRelationChoice .interfaces.ISelectWidget"/>
for="z3c.relationfield.interfaces.IRelationChoice .interfaces.ITextWidget" />
<adapter factory=".converters.RelationChoiceSelectWidgetConverter" />
<adapter factory=".converters.RelatedItemsDataConverter" />
<adapter factory=".converters.RelatedItemsDataConverter"
for="z3c.relationfield.interfaces.IRelationList .interfaces.ITextWidget" />
<adapter factory=".converters.RelationListSelectWidgetDataConverter" />
<adapter factory=".converters.LinkWidgetDataConverter" />

<!-- widget registration stuff -->
Expand Down
46 changes: 43 additions & 3 deletions plone/app/z3cform/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
"""
Expand All @@ -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."""
Expand Down Expand Up @@ -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:
Expand All @@ -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."""
Expand Down
3 changes: 2 additions & 1 deletion plone/app/z3cform/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 73f28f9

Please sign in to comment.