Skip to content

Commit c332cb0

Browse files
Documentation and example for pattern_options multiadapter (#1948)
* documentation and example for `pattern_options` multiadapter. * Update docs/backend/widgets.md Co-authored-by: Steve Piercy <[email protected]> * Update docs/backend/widgets.md Co-authored-by: Steve Piercy <[email protected]> * Apply suggestions from code review Co-authored-by: Steve Piercy <[email protected]> * removed Volto mention * Make multiadapter objects more obvious * update text --------- Co-authored-by: Steve Piercy <[email protected]>
1 parent c0b0dc4 commit c332cb0

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

docs/backend/widgets.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,56 @@ self.widgets["ds_pregu_pers"].disabled = "disabled"
472472
```
473473

474474

475+
### Customize existing widgets `pattern_options`
476+
477+
There is a special attribute called `pattern_options` which is primarily used in Classic UI for pattern configuration.
478+
479+
If you define your own schema, you can set this attribute with autoform directives.
480+
See {ref}`relations-configure-the-relateditemsfieldwidget-label` for an example.
481+
482+
To customize or extend `pattern_options` for existing schema widgets, you can create a `z3c.form.interface.IValue` multiadapter as shown.
483+
484+
```{code-block} python
485+
from z3c.form.interfaces import IForm
486+
from z3c.form.interfaces import IValue
487+
from z3c.form.interfaces import IWidget
488+
from zope.component impport adapter
489+
from zope.interface import implementer
490+
from zope.interface import Interface
491+
from zope.publisher.interfaces import IRequest
492+
from zope.schema.interfaces import IField
493+
494+
@implementer(IValue)
495+
@adapter(Interface, IRequest, IForm, IField, IWidget)
496+
class CustomPatternOptions:
497+
498+
def __init__(self, context, request, form, field, widget):
499+
self.context = context
500+
self.request = request
501+
self.form = form
502+
self.field = field
503+
self.widget = widget
504+
505+
def get(self):
506+
# return a dictionary with your custom options
507+
return {
508+
"myoption": "value",
509+
}
510+
```
511+
512+
This defines an adapter for every field widget in every form.
513+
514+
You can define the adapter more explicitly by providing different interfaces.
515+
See an example in {ref}`classic-ui-recipes-customize-pattern-options`.
516+
517+
Now register the `pattern_options` named adapter with ZCML as shown.
518+
519+
```xml
520+
<adapter factory=".CustomPatternOptions"
521+
name="pattern_options">
522+
```
523+
524+
475525
## Set widget templates
476526

477527
You might want to customize the template of a widget with custom HTML code.

docs/classic-ui/recipes.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,51 @@ Then register the adapter in ZCML.
4646
name="myproject-customclasses"
4747
/>
4848
```
49+
50+
(classic-ui-recipes-customize-pattern-options)=
51+
52+
## Customize `pattern_options`
53+
54+
The following example shows how to customize the {menuselection}`Favorites` menu in the `contentbrowser` pattern.
55+
56+
First create a multiadapter as shown.
57+
58+
```{code-block} python
59+
60+
from plone import api
61+
from plone.app.z3cform.interfaces import IContentBrowserWidget
62+
from plone.dexterity.interfaces import IDexterityContent
63+
from z3c.form.interfaces import IForm
64+
from z3c.form.interfaces import IValue
65+
from zope.component impport adapter
66+
from zope.interface import implementer
67+
from zope.publisher.interfaces import IRequest
68+
from zope.schema.interfaces import IField
69+
70+
@implementer(IValue)
71+
@adapter(IDexterityContent, IRequest, IForm, IField, IContentBrowserWidget)
72+
class ContentbrowserPatternOptions:
73+
74+
def __init__(self, context, request, form, field, widget):
75+
self.context = context
76+
self.request = request
77+
self.form = form
78+
self.field = field
79+
self.widget = widget
80+
81+
def get(self):
82+
portal_path = "/".join(api.portal.get().getPhysicalPath())
83+
return {
84+
"favorites": [
85+
{"title": "my favorite folder", "path": f"{portal_path}/path/to/my/favorite/folder"},
86+
{"title": "Portal", "path": portal_path},
87+
],
88+
}
89+
```
90+
91+
Then register it with ZCML as shown.
92+
93+
```xml
94+
<adapter factory=".ContentbrowserPatternOptions"
95+
name="pattern_options">
96+
```

0 commit comments

Comments
 (0)