Skip to content

Commit 420759b

Browse files
committed
adds docs for creating custom control panel
1 parent 861eada commit 420759b

File tree

1 file changed

+241
-6
lines changed

1 file changed

+241
-6
lines changed

docs/backend/control-panels.md

Lines changed: 241 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,170 @@ myst:
1212
# Control panels
1313

1414
## Adding a control panel
15+
16+
There are two approaches to creating a control panel for your Plone add-on:
17+
18+
### Approach 1: Using plonecli
19+
1520
To add a control panel to your add-on, you can use [`plonecli`](https://pypi.org/project/plonecli/) as follows:
1621

1722
```shell
1823
plonecli add controlpanel
1924
```
2025

21-
This will create the control panel Python file in the control panel's folder where you can define your control panel schema fields.
26+
This will create the control panel Python file in the control panel's folder where you can define your control panel schema fields.
27+
28+
### Approach 2: Creating a Custom Control Panel Manually
29+
30+
Creating a custom control panel involves these main steps:
31+
32+
1. Define an interface for your settings
33+
2. Create a form based on that interface
34+
3. Register the control panel view in ZCML
35+
4. Add the control panel to the Plone control panel listing
36+
5. Set default values in the registry
37+
38+
#### 1. Define the Settings Interface and Form
39+
40+
First, create a Python module that defines your control panel's settings interface and form class:
41+
42+
```python
43+
# mypackage/controlpanel/settings.py
44+
from zope import schema
45+
from zope.interface import Interface
46+
from plone.app.registry.browser.controlpanel import RegistryEditForm, ControlPanelFormWrapper
47+
from plone.z3cform import layout
48+
49+
class IMyControlPanelSettings(Interface):
50+
"""Schema for the control panel form."""
51+
52+
my_setting = schema.TextLine(
53+
title=u'My Setting',
54+
description=u'Enter the value for my setting',
55+
required=False,
56+
default=u''
57+
)
58+
59+
my_choice = schema.Choice(
60+
title=u'My Choice',
61+
description=u'Select a value for my choice',
62+
required=False,
63+
default=u'value3',
64+
values=['value1', 'value2', 'value3']
65+
)
66+
67+
class MyControlPanelForm(RegistryEditForm):
68+
"""Control panel form."""
69+
70+
schema = IMyControlPanelSettings
71+
schema_prefix = "my.addon"
72+
label = u"My Addon Settings"
73+
74+
# Wrap the form with plone.z3cform's ControlPanelFormWrapper to get the Plone
75+
# control panel look and feel
76+
MyControlPanelView = layout.wrap_form(MyControlPanelForm, ControlPanelFormWrapper)
77+
```
78+
79+
#### 2. Register the Control Panel View in ZCML
80+
81+
Next, register the control panel view in ZCML:
82+
83+
```xml
84+
<!-- mypackage/controlpanel/configure.zcml -->
85+
<configure
86+
xmlns="http://namespaces.zope.org/zope"
87+
xmlns:browser="http://namespaces.zope.org/browser"
88+
i18n_domain="mypackage">
89+
90+
<browser:page
91+
name="my-controlpanel"
92+
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
93+
class=".settings.MyControlPanelView"
94+
permission="cmf.ManagePortal"
95+
/>
96+
97+
</configure>
98+
```
99+
100+
Make sure to include this configure.zcml from your package's main configure.zcml:
101+
102+
```xml
103+
<!-- mypackage/configure.zcml -->
104+
<configure
105+
xmlns="http://namespaces.zope.org/zope"
106+
xmlns:i18n="http://namespaces.zope.org/i18n"
107+
i18n_domain="mypackage">
108+
109+
<!-- Other configuration -->
110+
111+
<include package=".controlpanel" />
112+
113+
</configure>
114+
```
115+
116+
#### 3. Add the Control Panel Entry
117+
118+
Create a controlpanel.xml in your package's GenericSetup profile to add your control panel to the Plone control panel listing:
119+
120+
```xml
121+
<!-- mypackage/profiles/default/controlpanel.xml -->
122+
<?xml version="1.0"?>
123+
<object name="portal_controlpanel">
124+
<configlet
125+
title="My Addon Settings"
126+
action_id="my-controlpanel"
127+
appId="my.addon"
128+
category="plone-general"
129+
condition_expr=""
130+
icon_expr="string:puzzle"
131+
url_expr="string:${portal_url}/@@my-controlpanel"
132+
visible="True">
133+
<permission>Manage portal</permission>
134+
</configlet>
135+
</object>
136+
```
137+
138+
The category attribute can be one of:
139+
- `plone-general` - General settings
140+
- `plone-content` - Content-related settings
141+
- `plone-users` - Users and groups settings
142+
- `plone-security` - Security settings
143+
- `plone-advanced` - Advanced settings
144+
145+
#### 4. Set Default Values in the Registry
146+
147+
Define default values for your settings in registry.xml:
148+
149+
```xml
150+
<!-- mypackage/profiles/default/registry.xml -->
151+
<?xml version="1.0"?>
152+
<registry>
153+
<records interface="mypackage.controlpanel.settings.IMyControlPanelSettings"
154+
prefix="my.addon">
155+
<value key="my_setting">default value</value>
156+
<value key="my_choice">value3</value>
157+
</records>
158+
</registry>
159+
```
160+
161+
#### 5. Accessing Your Settings in Code
162+
163+
You can access your settings in Python code as follows:
164+
165+
```python
166+
from plone.registry.interfaces import IRegistry
167+
from zope.component import getUtility
168+
169+
registry = getUtility(IRegistry)
170+
settings = registry.forInterface(IMyControlPanelSettings, prefix="my.addon")
171+
172+
# Now you can access the settings
173+
my_setting_value = settings.my_setting
174+
my_choice_value = settings.my_choice
175+
```
22176

23177
## Registering a Control panel
178+
24179
To manually register a view as a control panel, add the following registration to your `/profiles/default/controlpanel.xml`.
25180

26181
```xml
@@ -44,11 +199,91 @@ To manually register a view as a control panel, add the following registration t
44199
</object>
45200
```
46201

47-
```{seealso}
48-
See the chapter {ref}`training:controlpanel-label` from the Mastering Plone 6 Training.
202+
## Advanced Topics
203+
204+
### Using FieldSet for Grouping Fields
205+
206+
For complex control panels, you might want to group fields together:
207+
208+
```python
209+
from plone.supermodel import model
210+
211+
class IMyControlPanelSettings(Interface):
212+
213+
model.fieldset(
214+
'advanced',
215+
label=u"Advanced Settings",
216+
fields=['advanced_setting1', 'advanced_setting2']
217+
)
218+
219+
# Basic settings
220+
my_setting = schema.TextLine(
221+
title=u'My Setting',
222+
description=u'Enter the value for my setting',
223+
required=False
224+
)
225+
226+
# Advanced settings
227+
advanced_setting1 = schema.TextLine(
228+
title=u'Advanced Setting 1',
229+
required=False
230+
)
231+
232+
advanced_setting2 = schema.Bool(
233+
title=u'Advanced Setting 2',
234+
default=False
235+
)
49236
```
50237

51-
```{todo}
52-
Contribute to this documentation!
53-
See issue [Backend > Control Panels needs content](https://github.com/plone/documentation/issues/1304).
238+
### Common Schema Fields
239+
240+
Here are some commonly used schema field types:
241+
242+
- `schema.TextLine`: For single-line text
243+
- `schema.Text`: For multi-line text
244+
- `schema.Bool`: For boolean values
245+
- `schema.Int`: For integer values
246+
- `schema.Float`: For floating-point values
247+
- `schema.Choice`: For selection from a list of values
248+
- `schema.Datetime`: For date and time values
249+
- `schema.List`: For list of values
250+
251+
### Note on Updating Control Panel Fields
252+
253+
When you modify the fields in your control panel settings interface, the changes won't be automatically reflected in existing sites. You'll need to:
254+
255+
1. Run the appropriate upgrade steps, or
256+
2. Reinstall your add-on, or
257+
3. Test with a fresh site installation
258+
259+
## Troubleshooting
260+
261+
If your control panel doesn't appear or doesn't work as expected:
262+
263+
1. Verify that all ZCML is properly registered
264+
2. Check for errors in the Plone error log
265+
3. Ensure your GenericSetup profiles are correctly installed
266+
4. Validate that the interface path in registry.xml matches your actual Python path
267+
268+
## Complete Example
269+
270+
Below is a complete file structure for a simple add-on with a control panel:
271+
272+
```
273+
mypackage/
274+
├── __init__.py
275+
├── configure.zcml
276+
├── controlpanel/
277+
│ ├── __init__.py
278+
│ ├── configure.zcml
279+
│ └── settings.py
280+
└── profiles/
281+
└── default/
282+
├── controlpanel.xml
283+
├── metadata.xml
284+
└── registry.xml
285+
```
286+
287+
```{seealso}
288+
See the chapter {ref}`training:controlpanel-label` from the Mastering Plone 6 Training.
54289
```

0 commit comments

Comments
 (0)