Skip to content

Commit

Permalink
Merge pull request #125 from plone/vocabulary-relations
Browse files Browse the repository at this point in the history
Add support for more widgets when working with relationfieds
  • Loading branch information
pbauer authored Aug 12, 2021
2 parents 256a082 + 055daf9 commit 62080da
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 4 deletions.
1 change: 1 addition & 0 deletions news/125.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for more widget options when working with relation fields.
6 changes: 6 additions & 0 deletions plone/app/z3cform/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,13 @@
<adapter factory=".converters.AjaxSelectWidgetConverter" />
<adapter factory=".converters.QueryStringDataConverter" />
<adapter factory=".converters.RelationChoiceRelatedItemsWidgetConverter" />
<adapter factory=".converters.RelationChoiceRelatedItemsWidgetConverter"
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" />

<!-- widgets -->
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 62080da

Please sign in to comment.