Skip to content

Commit

Permalink
Support RelationList field with StaticCatalogVocabulary and SelectWid…
Browse files Browse the repository at this point in the history
…get. (#4614)

Co-authored-by: Steve Piercy <web@stevepiercy.com>
  • Loading branch information
ksuess and stevepiercy authored Apr 11, 2023
1 parent ef3f6f8 commit cafad1c
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 4 deletions.
102 changes: 100 additions & 2 deletions docs/source/recipes/widget.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,112 @@ const applyConfig = (config) => {
Based on this setup, Volto will render this field with the `TokenWidget`.


```{seealso}
See [storybook](https://6.dev-docs.plone.org/storybook) with available widgets.
(widget-relation-field-label)=

## Relation fields

A relation field is either a single relation field to hold at most one content object, `RelationChoice`, or a multi relation field, `RelationList`, that can hold more than one content object.

Relation fields can be edited and rendered with the `Select` widget.
The restriction on content types, workflow states, and so on can be done with a `StaticCatalogVocabulary`.

There are other vocabulary types and other widgets, including the `ObjectBrowser` widget.

(widget-relation-field-single-label)=

### Single relation field

Relation field (`RelationChoice`) with a named `StaticCatalogVocabulary` and `Select` widget:

```python
relationchoice_field_named_staticcatalogvocabulary = RelationChoice(
title="RelationChoice – named StaticCatalogVocabulary – Select widget",
description="field/relation: relationchoice_field_named_staticcatalogvocabulary",
vocabulary="relationchoice_field_named_staticcatalogvocabulary",
required=False,
)
directives.widget(
"relationchoice_field_named_staticcatalogvocabulary",
frontendOptions={
"widget": "select",
},
)
```

It is recommended to define the vocabulary as a named `StaticCatalogVocabulary` with the field/relation name as its name.
This allows the {guilabel}`relations` control panel to respect the defined restrictions to potential relation targets.

{file}`vocabularies.py`
```python
from plone.app.vocabularies.catalog import StaticCatalogVocabulary
from zope.interface import provider
from zope.schema.interfaces import IVocabularyFactory

@provider(IVocabularyFactory)
def ExamplesVocabularyFactory(context=None):
return StaticCatalogVocabulary(
{
"portal_type": ["example"],
"review_state": "published",
"sort_on": "sortable_title",
}
)
```

{file}`configure.zcml`
```xml
<utility
name="relationchoice_field_named_staticcatalogvocabulary"
component="example.contenttype.vocabularies.ExamplesVocabularyFactory"
/>
```

The `Select` widget is currently the default for `RelationChoice` fields with vocabulary.
Therefore the directive can be omitted.

```python
relationchoice_field_named_staticcatalogvocabulary = RelationChoice(
title="RelationChoice – named StaticCatalogVocabulary – Select widget",
description="field/relation: relationchoice_field_named_staticcatalogvocabulary",
vocabulary="relationchoice_field_named_staticcatalogvocabulary",
required=False,
)
```

(widget-relation-field-multi-label)=

### Multi relation field

Multi relation field (`RelationList`) with a named `StaticCatalogVocabulary`and `Select` widget:

```python
relationlist_field_named_staticcatalogvocabulary = RelationList(
title="RelationList – named StaticCatalogVocabulary – Select widget",
description="field/relation: relationlist_field_named_staticcatalogvocabulary",
value_type=RelationChoice(
vocabulary="relationlist_field_named_staticcatalogvocabulary",
),
required=False,
)
directives.widget(
"relationlist_field_named_staticcatalogvocabulary",
frontendOptions={
"widget": "select",
},
)
```


## Widget `isDisabled` Props

We can disable the input of a widget by passing props `isDisabled: true`.


## Available widgets

See [Storybook](https://6.docs.plone.org/storybook) with available widgets.


## Write a new widget

```{note}
Expand Down
1 change: 1 addition & 0 deletions news/4614.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support RelationList field with named StaticCatalogVocabulary and SelectWidget. @ksuess
2 changes: 1 addition & 1 deletion src/components/manage/Widgets/SelectUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export function normalizeSingleSelectOption(value, intl) {
throw new Error(`Unknown value type of select widget: ${value}`);
}

const token = value.token ?? value.value ?? 'no-value';
const token = value.token ?? value.value ?? value.UID ?? 'no-value';
const label =
(value.title && value.title !== 'None' ? value.title : undefined) ??
value.label ??
Expand Down
2 changes: 1 addition & 1 deletion src/components/manage/Widgets/SelectWidget.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class SelectWidget extends Component {

const isMulti = this.props.isMulti
? this.props.isMulti
: id === 'roles' || id === 'groups';
: id === 'roles' || id === 'groups' || this.props.type === 'array';

return (
<FormFieldWrapper {...this.props}>
Expand Down
1 change: 1 addition & 0 deletions src/config/Widgets.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export const widgetMapping = {
select_querystring_field: SelectMetadataWidget,
autocomplete: SelectAutoComplete,
color_picker: ColorPickerWidget,
select: SelectWidget,
},
vocabulary: {
'plone.app.vocabularies.Catalog': ObjectBrowserWidget,
Expand Down

0 comments on commit cafad1c

Please sign in to comment.