Skip to content

Commit ac8be26

Browse files
committed
Clean up layers.md, add interface to Glossary
1 parent c2b1c5d commit ac8be26

File tree

2 files changed

+144
-115
lines changed

2 files changed

+144
-115
lines changed

docs/classic-ui/layers.md

Lines changed: 134 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,48 @@
11
---
2-
html_meta:
3-
"description": "Layers allow you to enable and disable views and other site functionality based on installed add-ons and themes."
4-
"property=og:description": "Layers allow you to enable and disable views and other site functionality based on installed add-ons and themes."
5-
"property=og:title": "Layers"
6-
"keywords": "layer, layers,browser layer, views, viewlets, portlets"
2+
myst:
3+
html_meta:
4+
"description": "Layers allow you to enable and disable views and other site functionality based on installed add-ons and themes."
5+
"property=og:description": "Layers allow you to enable and disable views and other site functionality based on installed add-ons and themes."
6+
"property=og:title": "Layers"
7+
"keywords": "layer, layers,browser layer, views, viewlets, portlets"
78
---
89

910
(classic-ui-layers-label)=
1011

1112
# Layers
1213

13-
Layers allow you to activate different code paths and modules depending on
14-
the external configuration.
14+
Layers allow you to activate different code paths and modules depending on the external configuration.
15+
Layers are useful in the following scenarios.
1516

16-
Examples:
17-
18-
- Code belonging to a theme is only active when that theme has been selected.
19-
- Mobile browsing code is only active when the site is being browsed on a
20-
mobile phone.
17+
- Code belonging to a theme is only active when that theme has been selected.
18+
- Mobile browsing code is only active when the site is being browsed on a mobile phone.
2119

2220
Layers are marker interfaces applied to the {term}`HTTPRequest` object.
23-
They are usually used in conjunction with {term}`ZCML` directives to
24-
dynamically activate various parts
25-
of the configuration (theme files, add-on product functionality).
21+
They are usually used in conjunction with {term}`ZCML` directives to dynamically activate various parts of the configuration, such as theme files or add-on product functionality.
22+
23+
Layers ensure that only one add-on product can override the specific Plone instance functionality in your site at a time, while still allowing you to have possibly conflicting add-on products in your buildout and ZCML.
24+
Multiple Plone site instances can share the same ZCML and code files.
25+
26+
Many ZCML directives take the optional `layer` parameter.
27+
See example [resourceDirectory](http://apidoc.zope.org/++apidoc++/ZCML/http_co__sl__sl_namespaces.zope.org_sl_browser/resourceDirectory/index.html).
2628

27-
Layers ensure that only one add-on product can override the specific Plone
28-
instance functionality in your site at a time, while still allowing you
29-
to have possibly conflicting add-on products in your buildout and
30-
ZCML. Remember that multiple Plone site instances can share
31-
the same ZCML and code files.
29+
Layers are activated when an add-on product is installed or a certain theme is activated.
3230

33-
Many ZCML directives take the optional `layer` parameter. See example,
34-
[resourceDirectory](http://apidoc.zope.org/++apidoc++/ZCML/http_co__sl__sl_namespaces.zope.org_sl_browser/resourceDirectory/index.html)
3531

36-
Layers are activated when an add-on product is installed or a certain
37-
theme is picked.
32+
(classic-ui-using-layers-label)=
3833

3934
## Using layers
4035

41-
Some ZCML directives for example: `browser:page` take a `layer` attribute.
36+
Some ZCML directives take a `layer` attribute, such as `browser:page`.
4237

4338
Given the following:
4439

45-
- A layer interface defined in Python code: `plonetheme.yourthemename.interfaces.IThemeSpecific`
46-
- Your add-on or theme package installed through add-on product installer on your site instance
40+
- A layer interface defined in Python code, `plonetheme.yourthemename.interfaces.IThemeSpecific`.
41+
- Your add-on or theme package installed through the add-on product installer on your site instance.
4742

48-
then views and viewlets from your product can be enabled on the site
49-
instance using the following ZCML:
43+
Then views and viewlets from your product can be enabled on the site instance using the following ZCML:
5044

51-
```
45+
```xml
5246
<!-- Site actions override in YourTheme -->
5347
<browser:viewlet
5448
name="plone.site_actions"
@@ -59,75 +53,87 @@ instance using the following ZCML:
5953
/>
6054
```
6155

56+
57+
(classic-ui-unconditional-overrides-label)=
58+
6259
### Unconditional overrides
6360

64-
If you want to override a view or a viewlet unconditionally for all sites
65-
without the add-on product installer
66-
support you need to use `overrides.zcml`.
61+
If you want to override a view or a viewlet unconditionally for all sites without the add-on product installer support, you need to use `overrides.zcml`.
62+
63+
64+
(classic-ui-creating-a-layer-label)=
6765

6866
## Creating a layer
6967

68+
69+
(classic-ui-theme-layer-label)=
70+
7071
### Theme layer
7172

72-
Theme layers can be created via the following steps:
73+
Theme layers can be created through the following steps.
7374

74-
1. Subclass an interface from `IDefaultPloneLayer`:
75+
1. Subclass an interface from `IDefaultPloneLayer`:
7576

76-
```
77-
from plone.theme.interfaces import IDefaultPloneLayer
77+
```python
78+
from plone.theme.interfaces import IDefaultPloneLayer
7879

79-
class IThemeSpecific(IDefaultPloneLayer):
80-
"""Marker interface that defines a Zope 3 skin layer bound to a Skin
81-
Selection in portal_skins.
82-
If you need to register a viewlet only for the "YourSkin"
83-
skin, this is the interface that must be used for the layer attribute
84-
in YourSkin/browser/configure.zcml.
85-
"""
86-
```
8780

88-
2. Register it in ZCML. The name must match the theme name.
81+
class IThemeSpecific(IDefaultPloneLayer):
82+
"""
83+
Marker interface that defines a Zope 3 skin layer bound to a Skin
84+
Selection in portal_skins.
85+
If you need to register a viewlet only for the "YourSkin"
86+
skin, this is the interface that must be used for the layer attribute
87+
in YourSkin/browser/configure.zcml.
88+
"""
89+
```
8990

90-
```xml
91-
<interface
92-
interface=".interfaces.IThemeSpecific"
93-
type="zope.publisher.interfaces.browser.IBrowserSkinType"
94-
name="SitsSkin"
95-
/>
96-
```
91+
2. Register it in ZCML.
92+
The name must match the theme name.
9793

98-
3. Register and set your theme as the default theme in `profiles/default/skins.xml`. Theme layers require that they are set as the default theme and not just activated on your Plone site. Example:
94+
```xml
95+
<interface
96+
interface=".interfaces.IThemeSpecific"
97+
type="zope.publisher.interfaces.browser.IBrowserSkinType"
98+
name="SitsSkin"
99+
/>
100+
```
99101

100-
```xml
101-
<object name="portal_skins" allow_any="False" cookie_persistence="False"
102-
default_skin="SitsSkin">
102+
3. Register and set your theme as the default theme in `profiles/default/skins.xml`.
103+
Theme layers require that they are set as the default theme and not just activated on your Plone site.
104+
Example:
103105

104-
<!-- define skins-based folder objects here if any -->
106+
```xml
107+
<object name="portal_skins" allow_any="False" cookie_persistence="False"
108+
default_skin="SitsSkin">
109+
110+
<!-- define skins-based folder objects here if any -->
111+
112+
<skin-path name="SitsSkin" based-on="Plone Default">
113+
<layer name="plone_skins_style_folder_name"
114+
insert-before="*"/>
115+
</skin-path>
116+
117+
</object>
118+
```
105119

106-
<skin-path name="SitsSkin" based-on="Plone Default">
107-
<layer name="plone_skins_style_folder_name"
108-
insert-before="*"/>
109-
</skin-path>
110120

111-
</object>
112-
```
121+
(classic-ui-add-on-layer-for-clean-extensions-label)=
113122

114123
### Add-on layer for clean extensions
115124

116125
An add-on product layer is enabled when an add-on product is installed.
117-
Since one Zope application server may contain several Plone sites,
118-
you need to keep enabled code paths separate by using add-on layers -
119-
otherwise all views and viewlets apply to all sites in one Zope application server.
126+
Since one Zope application server may contain several Plone sites, you need to keep enabled code paths separate by using add-on layers.
127+
Otherwise, all views and viewlets apply to all sites in one Zope application server.
120128

121-
- You can enable views and viewlets specific to functional add-ons.
122-
- Unlike theme layers, add-on layers depend on the activated add-on
123-
products, not on the selected theme.
129+
- You can enable views and viewlets specific to functional add-ons.
130+
- Unlike theme layers, add-on layers depend on the activated add-on products, not on the selected theme.
124131

125-
An add-on layer is a marker interface which is applied on the
126-
{term}`HTTPRequest` object by Plone core logic.
132+
An add-on layer is a marker interface which is applied on the {term}`HTTPRequest` object by Plone core logic.
127133

128134
First create an {term}`interface` for your layer in `your.product.interfaces.py`:
129135

130-
```
136+
```python
131137
""" Define interfaces for your add-on.
132138
"""
133139

@@ -143,8 +149,7 @@ class IAddOnInstalled(zope.interface.Interface):
143149
"""
144150
```
145151

146-
You then need to refer to this in the `profile/default/browserlayer.xml`
147-
file of your add-on installer to use it:
152+
You then need to refer to this in the `profile/default/browserlayer.xml` file of your add-on installer to use it:
148153

149154
```xml
150155
<layers>
@@ -160,44 +165,45 @@ The add-on layer registry is persistent and stored in the database.
160165
The changes to add-on layers are applied only when add-ons are installed or uninstalled.
161166
```
162167

163-
More information
168+
```{seealso}
169+
https://pypi.python.org/pypi/plone.browserlayer
170+
```
164171

165-
- <https://pypi.python.org/pypi/plone.browserlayer>
166172

173+
(classic-ui-add-on-layer-for-changing-existing-behavior-label)=
167174

168175
### Add-on layer for changing existing behavior
169176

170-
You can also use layers to modify the behavior of plone or another Add-on.
177+
You can also use layers to modify the behavior of Plone or another add-on.
171178

172-
To make sure that your own view is used, your Layer must be more specific than the layer where original view is registered.
179+
To make sure that your own view is used, your layer must be more specific than the layer where the original view is registered.
173180

174-
For example, some z3cform things register their views on the `IPloneFormLayer` from plone.app.z3cform.interfaces.
181+
For example, some `z3cform` things register their views on the `IPloneFormLayer` from `plone.app.z3cform.interfaces`.
175182

176-
If you want to override the ploneform-macros view that is registered on the `IPloneFormLayer`, your own Layer must be a subclass of IPloneFormLayer.
183+
If you want to override the `ploneform-macros` view that is registered on the `IPloneFormLayer`, your own layer must be a subclass of `IPloneFormLayer`.
177184

178-
If a view does not declare a specific Layer, it becomes registered on the `IDefaultBrowserLayer` from zope.publisher.interfaces.browser.IDefaultBrowserLayer.
185+
If a view does not declare a specific layer, it becomes registered on the `IDefaultBrowserLayer` from `zope.publisher.interfaces.browser.IDefaultBrowserLayer`.
179186

180187

188+
(classic-ui-manual-layers-label)=
189+
181190
### Manual layers
182191

183-
Apply your layer to the {term}`HTTPRequest` in the `before_traverse` hook or
184-
before you call the code which looks up the interfaces.
192+
Apply your layer to the {term}`HTTPRequest` in the `before_traverse` hook, or before you call the code which looks up the interfaces.
185193

186-
In the example below we turn on a layer for the request which is later
187-
checked by the rendering code.
194+
In the example below, we turn on a layer for the request, which is later checked by the rendering code.
188195
This way some pages can ask for special View/Viewlet rendering.
189196

190-
Example:
191-
192-
```
197+
```python
193198
# Defining layer
194199

195200
from zope.publisher.interfaces.browser import IBrowserRequest
196201

197202
class INoHeaderLayer(IBrowserRequest):
198-
""" When applied to HTTP request object, header animations or images are not rendered on this.
203+
""" When applied to HTTP request object, header animations
204+
or images are not rendered on this.
199205
200-
If this layer is on request do not render header images.
206+
If this layer is on request, do not render header images.
201207
This allows uncluttered editing of header animations and images.
202208
"""
203209

@@ -219,42 +225,48 @@ class EditHeaderAnimationsView(FormWrapper):
219225
return FormWrapper.__call__(self)
220226
```
221227

228+
229+
(classic-ui-troubleshooting-instructions-for-layers-label)=
230+
222231
## Troubleshooting instructions for layers
223232

224-
- Check that your view or whatever is working without a layer assigned
225-
(globally);
226-
- Check that `configure.zcml` has a layer entry. Put some garbage to
227-
trigger a syntax error in `configure.zcml` to make sure that it is being
228-
loaded;
229-
- Add-on layer: check that `profiles/default/browserlayer.xml` has a
230-
matching entry with a matching name;
231-
- Theme layer: if it's a theme layer, check that there is a matching
232-
`skins.xml` entry
233-
- Check that layer name is correctly spelt in the view declaration.
233+
- Check that your view is working without a layer assigned globally.
234+
- Check that `configure.zcml` has a layer entry.
235+
Put some garbage to trigger a syntax error in `configure.zcml` to make sure that it is being loaded.
236+
- Add-on layer: check that `profiles/default/browserlayer.xml` has a matching entry with a matching name.
237+
- Theme layer: if it is a theme layer, check that there is a matching `skins.xml` entry.
238+
- Check that the layer name is spelled correctly in the view declaration.
239+
240+
241+
(classic-ui-checking-active-layers-label)=
234242

235243
## Checking active layers
236244

245+
246+
(classic-ui-layers-are-activated-on-the-current-request-object-label)=
247+
237248
### Layers are activated on the current request object
238249

239250
Example:
240251

241-
```
252+
```python
242253
if INoHeaderLayer.providedBy(self.request):
243254
# The page has asked to suspend rendering of the header animations
244255
return ""
245256
```
246257

258+
259+
(classic-ui-active-themes-and-add-on-products-label)=
260+
247261
### Active themes and add-on products
248262

249-
The `registered_layers()` method returns a list of all layers active on
250-
the site.
251-
Note that this is different to the list of layers which are applied on the
252-
current HTTP request object:
253-
the request object may contain manually activated layers.
263+
The `registered_layers()` method returns a list of all layers active on the site.
264+
Note that this is different from the list of layers which are applied on the current HTTP request object.
265+
The request object may contain manually activated layers.
254266

255267
Example:
256268

257-
```
269+
```python
258270
from interfaces import IThemeSpecific
259271
from plone.browserlayer.utils import registered_layers
260272

@@ -266,26 +278,33 @@ else:
266278
pass
267279
```
268280

281+
282+
(classic-ui-getting-active-theme-layer-label)=
283+
269284
### Getting active theme layer
270285

271286
Only one theme layer can be active at once.
272287

273288
The active theme name is defined in `portal_skins` properties.
274289
This name can be resolved to a theme layer.
275290

291+
292+
(classic-ui-debugging-active-layers-label)=
293+
276294
### Debugging active layers
277295

278-
You can check the activated layers from HTTP request object by looking at
279-
`self.request.__provides__.__iro__`.
280-
Layers are evaluated from zero index (highest priority) the last index
281-
(lowest priority).
296+
You can check the activated layers from the HTTP request object by looking at `self.request.__provides__.__iro__`.
297+
Layers are evaluated from zero index (highest priority) to the last index (lowest priority).
298+
299+
300+
(classic-ui-testing-layers-label)=
282301

283302
## Testing Layers
284303

285-
Plone testing tool kits won't register layers for you, you have to do it
286-
yourself somewhere in the boilerplate code:
304+
Plone testing tool kits will not register layers for you.
305+
You have to do it yourself somewhere in the boilerplate code, as shown in the following example.
287306

288-
```
307+
```python
289308
from zope.interface import directlyProvides
290309

291310
directlyProvides(self.portal.REQUEST, IThemeLayer)

0 commit comments

Comments
 (0)