Skip to content

Commit 00e56f3

Browse files
committed
Clean up syntax and grammar, replace adapter with price_for_context.
1 parent 5e09380 commit 00e56f3

File tree

1 file changed

+109
-94
lines changed

1 file changed

+109
-94
lines changed

docs/backend/behaviors.md

Lines changed: 109 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ myst:
1111

1212
# Behaviors
1313

14-
## What are Behaviors in Plone
15-
1614
In Plone, behaviors are a way to add reusable functionality to content objects without modifying the objects themselves.
1715
Behaviors are essentially small chunks of code that can be plugged onto content types to provide new features or capabilities.
1816

@@ -22,7 +20,7 @@ A Plone behavior could be used to
2220
- add logic as part of the adapter,
2321
- enable a particular event handler,
2422
- enable one or more views, viewlets, or other UI components,
25-
- do anything else which may be expressed in code via an adapter and/or marker interface.
23+
- do anything else which may be expressed in code via an adapter or marker interface.
2624

2725
Behaviors can be added to content types on an as-needed basis, allowing for a high degree of flexibility and customization.
2826

@@ -38,71 +36,82 @@ Overall, behaviors are an important part of the Plone content management system
3836

3937
## Built-in behaviors
4038

41-
| short name | Title | Desription |
42-
|-------------|------------------|-------------------------------|
43-
| plone.allowdiscussion | Allow discussion | Allow discussion on this item |
44-
| plone.basic | Basic metadata | Adds title and description fields. |
45-
| plone.categorization | Categorization | Adds keywords and language fields. |
46-
| plone.collection | Collection | Adds collection behavior |
47-
| plone.publication | Date range | Adds effective date and expiration date fields. |
48-
| plone.dublincore | Dublin Core metadata | Adds standard metadata fields (equals Basic metadata + Categorization + Effective range + Ownership |
49-
| plone.eventattendees | Event Attendees | Attendees extension for Events. |
50-
| plone.eventbasic | Event Basic | Basic Event schema. |
51-
| plone.eventcontact | Event Contact | Contact extension for Events. |
52-
| plone.eventlocation | Event Location | Location extension for Events. |
53-
| plone.eventrecurrence | Event Recurrence | Recurrence extension for Events. |
54-
| plone.excludefromnavigation | Exclude From navigation | Allow items to be excluded from navigation |
55-
| plone.constraintypes| Folder Addable Constrains | Restrict the content types that can be added to folderish content |
56-
| plone.textindexer | Full-Text Indexing | Enables the enhanced full-text indexing for a content type. If a field in the schema is marked with the `searchable` directive, its content gets added to the `SearchableText` index in the catalog |
57-
| plone.leadimage | Lead Image | Adds image and image caption fields |
58-
| plone.locking | Locking | Locking support for dexterity |
59-
| plone.translatable | Multilingual Support | Make this content type multilingual aware. Multilingual support must be installed. |
60-
| plone.namefromfilename | Name from file name | Automatically generate short URL name for content based on its primary field file name
61-
| plone.namefromtitle | Name from title | Automatically generate short URL name for content based on its initial title
62-
| plone.navigationroot | Navigation root | Make all items of this type a navigation root |
63-
| plone.nextpreviousenabled | Next previous navigation | Enable next previous navigation for all items of this type |
64-
| plone.nextprevioustoggle | Next previous navigation toggle | Allow items to have next previous navigation enabled |
65-
| plone.ownership | Ownership | Adds creator, contributor, and rights fields. |
66-
| plone.relateditems | Related items | Adds the ability to assign related items |
67-
| plone.richtext | RichText | Adds richtext behavior |
68-
| plone.shortname | Short name | Gives the ability to rename an item from its edit form. |
69-
| plone.tableofcontents | Table of contents | Adds a table of contents |
70-
| plone.thumb_icon | Thumbs and icon handling | Options to suppress thumbs and/or icons and to override thumb size in listings, tables etc.
71-
| plone.versioning | Versioning | Versioning support with CMFEditions |
72-
| volto.blocks | Blocks | Enables Volto Blocks support |
73-
| volto.blocks.editable.layout | Blocks (Editable Layout) | Enables Volto Blocks (editable layout) support |
74-
| volto.head_title | Head title field | Adds Head title field |
75-
| volto.navtitle | Navigation title | Navigation title used in sections, menus and doormats |
76-
| volto.preview_image | Preview Image | Preview image for listings |
77-
| volto.preview_image_link | Preview Image Link | Preview image for listings based on links |
39+
To view a complete list of built-in behaviors, browse to {guilabel}`Content Types` control panel, then click {guilabel}`Page` (or any other content type), then {guilabel}`Behaviors`.
40+
41+
| short name | Title | Desription |
42+
|---|---|---|
43+
| `plone.allowdiscussion` | Allow discussion | Allow discussion on this item |
44+
| `plone.basic` | Basic metadata | Adds title and description fields. |
45+
| `volto.blocks` | Blocks | Enables Volto Blocks support |
46+
| `volto.blocks.editable.layout` | Blocks (Editable Layout) | Enables Volto Blocks (editable layout) support |
47+
| `plone.categorization` | Categorization | Adds keywords and language fields. |
48+
| `plone.collection` | Collection | Adds collection behavior |
49+
| `plone.publication` | Date range | Adds effective date and expiration date fields. |
50+
| `plone.dublincore` | Dublin Core metadata | Adds standard metadata fields (equals Basic metadata + Categorization + Effective range + Ownership |
51+
| `plone.eventattendees` | Event Attendees | Attendees extension for Events. |
52+
| `plone.eventbasic` | Event Basic | Basic Event schema. |
53+
| `plone.eventcontact` | Event Contact | Contact extension for Events. |
54+
| `plone.eventlocation` | Event Location | Location extension for Events. |
55+
| `plone.eventrecurrence` | Event Recurrence | Recurrence extension for Events. |
56+
| `plone.excludefromnavigation` | Exclude From navigation | Allow items to be excluded from navigation |
57+
| `plone.constraintypes` | Folder Addable Constrains | Restrict the content types that can be added to folderish content |
58+
| `plone.textindexer` | Full-Text Indexing | Enables the enhanced full-text indexing for a content type. If a field in the schema is marked with the `searchable` directive, its content gets added to the `SearchableText` index in the catalog |
59+
| `volto.head_title` | Head title field | Adds Head title field |
60+
| `plone.leadimage` | Lead Image | Adds image and image caption fields |
61+
| `plone.locking` | Locking | Locking support for dexterity |
62+
| `plone.translatable` | Multilingual Support | Make this content type multilingual aware. Multilingual support must be installed. |
63+
| `plone.namefromfilename` | Name from file name | Automatically generate short URL name for content based on its primary field file name
64+
| `plone.namefromtitle` | Name from title | Automatically generate short URL name for content based on its initial title
65+
| `plone.navigationroot` | Navigation root | Make all items of this type a navigation root |
66+
| `volto.navtitle` | Navigation title | Navigation title used in sections, menus and doormats |
67+
| `plone.nextpreviousenabled` | Next previous navigation | Enable next previous navigation for all items of this type |
68+
| `plone.nextprevioustoggle` | Next previous navigation toggle | Allow items to have next previous navigation enabled |
69+
| `plone.ownership` | Ownership | Adds creator, contributor, and rights fields. |
70+
| `volto.preview_image` | Preview Image | Preview image for listings |
71+
| `volto.preview_image_link` | Preview Image Link | Preview image for listings based on links |
72+
| `plone.relateditems` | Related items | Adds the ability to assign related items |
73+
| `plone.richtext` | RichText | Adds richtext behavior |
74+
| `plone.shortname` | Short name | Gives the ability to rename an item from its edit form. |
75+
| `plone.tableofcontents` | Table of contents | Adds a table of contents |
76+
| `plone.thumb_icon` | Thumbs and icon handling | Options to suppress thumbs and/or icons and to override thumb size in listings, tables etc.
77+
| `plone.versioning` | Versioning | Versioning support with CMFEditions |
78+
79+
```{todo}
80+
For each behavior in the table above, one may view the source code of the checkbox (its `name` attribute) to view its Short Name.
81+
An issue has been created to better expose these in the user interface.
82+
[Control panel for Content Type > Behaviors short names not displayed to user Products.CMFPlone#3706](https://github.com/plone/Products.CMFPlone/issues/3706)
83+
```
7884

7985
## Adding or removing a behavior from a content type
8086

8187
There are two ways to add or remove a behavior on a content type:
8288

83-
- Through the web using the {guilabel}`Content Types` control panel.
84-
- Using a custom add-on GenericSetup profile.
89+
- Through the web using the {guilabel}`Content Types` control panel.
90+
- Using a custom add-on `GenericSetup` profile.
91+
92+
93+
### Through the web
8594

86-
### Through the Web
95+
1. Go to the {guilabel}`Site Setup` and chose the {guilabel}`Content Types` control panel.
96+
2. Select the content type to which you want to add or remove a behavior.
97+
3. Then click on the {guilabel}`Behaviors` tab of the settings of the content type.
98+
4. A list of all available behaviors appears.
99+
Select or deselect the checkbox of the behavior you want to add to or remove from the type.
100+
5. Save the form by clicking on the {guilabel}`Save` button at the bottom of the page.
87101

88-
1. Go to the {guilabel}`Site Setup` and chose the {guilabel}`Content Types` control panel.
89-
2. Select the content type to which you want to add or remove a behavior.
90-
3. Then click on the {guilabel}`Behaviors` tab of the settings of the content type.
91-
4. A list of all available behaviors appears.
92-
Select or deselect the checkbox of the behavior you want to add to or remove from the type.
93-
5. Save the form by clicking on the {guilabel}`Save` button at the bottom of the page.
94102

95-
### Using a GenericSetup profile
103+
### Using a `GenericSetup` profile
96104

97105
Given you already have a custom add-on with a `profiles/default` directory, and you created a custom behavior named `mybehavior.subtitle`.
98106

99107
If you want to enable a behavior on an existing content type, create a new directory `types` under `profiles/default`.
100108
In the `types` directory, create a file named the same as the content type you want to change.
101-
In the example here, you want to add a behavior to the built-in Event content type.
102-
The file to create is named `Event.xml` and it is a {term}`Factory Type Information` (FTI) definition.
103-
You need to change only the behaviors configuration.
109+
In the example here, you want to add a behavior to the built-in `Event` content type.
110+
Create a file named `Event.xml`.
111+
It is a {term}`Factory Type Information` (FTI) definition.
112+
You need to change only the behavior's configuration.
104113
All other parts can be ignored.
105-
This looks like so:
114+
The file `Event.xml` contains the following.
106115

107116
```xml
108117
<?xml version="1.0"?>
@@ -117,7 +126,7 @@ This looks like so:
117126
</object>
118127
```
119128

120-
After you apply the profile (or uninstall and install the custom add-on), the behavior is effective on the Event content type.
129+
After you apply the profile (or uninstall and install the custom add-on), the behavior is effective on the `Event` content type.
121130

122131

123132
## Custom behaviors
@@ -128,9 +137,10 @@ Schema-only behaviors
128137
: These behaviors have only a schema with fields.
129138

130139
Full behaviors
131-
: A python class containing the logic of the behavior, an interface or schema defining the contract of the behavior, and a marker interface applicable to a content type.
140+
: A Python class containing the logic of the behavior, an interface or schema defining the contract of the behavior, and a marker interface applicable to a content type.
132141

133-
### Creating a schema-only behavior
142+
143+
### Create a schema-only behavior
134144

135145
Given you want to add a field `subtitle` to some existing content types of your custom add-on.
136146

@@ -169,7 +179,7 @@ After a restart of Plone, the behavior can be added to the content type in the {
169179
The add and edit forms contain a new field `Subtitle`.
170180

171181
This field is not displayed in most views.
172-
To display the data entered in this field, you need to modify the page template by adding the field `context.subtitle`.
182+
To display the entered data in this field, you need to modify the page template by adding the field `context.subtitle`.
173183

174184
### Creating a behavior with an adapter and factory
175185

@@ -231,27 +241,26 @@ class PriceAdapter:
231241
@property
232242
def price_gross(self):
233243
return self.price_net + self.price_vat
234-
235244
```
236245

237-
The registration in the `configure.zcml` looks like so:
246+
The registration in the `configure.zcml`:
238247

239-
```XML
240-
<plone:behavior
241-
factory=".price.PriceAdapter"
242-
for=".price.IPriceMarker"
243-
marker=".price.IPriceMarker"
244-
name="myproject.price"
245-
provides=".price.IPriceBehavior"
246-
title="Price with net, VAT and gross"
247-
/>
248-
```
248+
```xml
249+
<plone:behavior
250+
factory=".price.PriceAdapter"
251+
for=".price.IPriceMarker"
252+
marker=".price.IPriceMarker"
253+
name="myproject.price"
254+
provides=".price.IPriceBehavior"
255+
title="Price with net, VAT and gross"
256+
/>
257+
```
249258

250259
After a restart of Plone, the behavior can be added to the content type in the {guilabel}`Content Types` control panel.
251260
The add and edit forms contain a new field `Price (net)`.
252261

253262
This field is not displayed in most views.
254-
To display the data entered in this field, you need to modify the page template by adding the `price_net` field as `context.price_net`.
263+
To display the entered data in this field, you need to modify the page template by adding the `price_net` field as `context.price_net`.
255264
To access the `price_vat` and `price_gross` fields from a browser view, you need to get the adapter from the context of the view:
256265

257266
(behavior-code-example)=
@@ -262,30 +271,32 @@ from .price import IPriceBehavior
262271
class SomeViewClass:
263272

264273
def vat(self):
265-
adapter = IPriceBehavior(context)
266-
return adapter.price_vat
274+
price_for_context = IPriceBehavior(context)
275+
return price_for_context.price_vat
267276

268277
def gross(self):
269-
adapter = IPriceBehavior(context)
270-
return adapter.price_gross
278+
price_for_context = IPriceBehavior(context)
279+
return price_for_context.price_gross
271280
```
272281

273-
### Creating a behavior with PloneCLI
282+
### Create a behavior with PloneCLI
274283

275284
To add a behavior to your add-on, you can use PloneCLI as follows:
276285

277286
```shell
278287
plonecli add behavior
279288
```
280289

281-
This will create the behavior Python file in the `behaviors` folder, where you can define your behaviors schema fields, and registers the behavior in the `configure.zcml`.
290+
This will create the behavior Python file in the `behaviors` folder where you can define your behavior's schema fields, and registers the behavior in the `configure.zcml`.
291+
282292

283293
### Further reading on working with behaviors
284294

285295
```{seealso}
286296
See the chapter {ref}`training:behaviors1-label` from the Mastering Plone 6 Training.
287297
```
288298

299+
289300
## How behaviors work
290301

291302
```{note}
@@ -294,35 +305,39 @@ You do not *need* to know this, but it may help if you run into problems.
294305
```
295306

296307
In Plone, behaviors can be globally enabled on content types at runtime.
297-
With add-ons, behaviors can even be enabled even on a single content object or for a whole subtree in the content hierarchy.
308+
With add-ons, behaviors can be enabled even on a single content object or for a whole subtree in the content hierarchy.
309+
298310

299311
### Interfaces and adapters
312+
300313
To explain interfaces and adapters, let's begin with an analogy using electrical systems.
301314

302315
An electrical outlet provides an interface through which electricity passes.
303316
When you travel to another country, you may need an outlet adapter for the outlet (the interface).
304317
For example, assume you have a device that has a plug for Schuko outlets, and in Italy there are Type L outlets.
305-
If we were to represent the behavior of choosing the correct power adapter in Plone, you would do the following.
306-
307-
- You need an electrical adapter for your Schuko plug.
308-
1. you look at the outlet and see it is TypeL.
309-
2. you look in your box containing different adapters and choose one the correct electrical adapter to use, and
310-
3. plug that into the wall outlet.
311-
4. Finally you can use your Schuko providing device on an Italian TypeL outlet.
312-
- In Python you call `getAdapter(context, ISchuko)` (context is here the outlet) which then
313-
1. determine the type of interface provided by the `context` and as a result it finds `ITypeL`.
314-
2. looks in the component registry if there is a class that adapts to `ITypeL` and at the same time provides the requested `ISchuko`.
315-
3. initializes the adapter class with the context and return it as the result
316-
4. Finally the `ISchuko` providing adapter can be used on a `ITypeL` providing context.
318+
If we were to represent the behavior of choosing the correct outlet adapter in Plone, you would do the following.
319+
320+
- You need an outlet adapter for your Schuko plug.
321+
1. You look at the outlet and see it is Type L.
322+
2. You look in your box containing different adapters and choose the correct outlet adapter to use.
323+
3. You plug that into the wall outlet.
324+
4. Finally, you can use your Schuko providing device on an Italian Type L outlet.
325+
- In Python, you would call `getAdapter(context, ISchuko)` (context is here the outlet type), which would then do the following.
326+
1. Determine the type of interface provided by the `context`.
327+
As a result, it finds `ITypeL` interface.
328+
2. Looks in the component registry if there is a class that adapts to `ITypeL`.
329+
At the same time, it provides the requested `ISchuko` adapter.
330+
3. Initializes the adapter class with the context, and returns it as the result.
331+
4. Finally, the `ISchuko` providing adapter can be used on a `ITypeL` providing context.
317332

318333
This process of choosing the right adapter based on the information of the context and the requested interface implements the design pattern of an abstract factory.
319334

320335
Similarly, using the {ref}`behavior code example <behavior-code-example>` above:
321336

322-
- You would call an abstract factory with `getAdapter(context, IPriceBehavior)` to get an adapter.
337+
- You would call an abstract factory with `getAdapter(context, IPriceBehavior)` to get an adapter, `price_for_context`.
323338
Although it is an interface, it is more of a shortcut to factory usage.
324-
- The adapter that is specific to the given content type is assigned to the variable `adapter`.
325-
Now you can use `adapter` for whatever you like.
339+
- The adapter that is specific to the given content type is assigned to the variable `price_for_context`.
340+
Now you can use `price_for_context` for whatever you like.
326341

327342
When a behavior is enabled for a particular object, it will be possible to adapt that object to the behavior's interface.
328343
Otherwise, when the behavior is disabled, adaptation will fail or falls back to a more generic adapter, if any is registered.
@@ -353,6 +368,6 @@ The [README file of `plone.behavior`](https://github.com/plone/plone.behavior/bl
353368

354369
### Lookup and provide
355370

356-
Plone content objects have logic to look up the behaviors' names registered from their types' configuration, the Factory Type Information (FTI).
371+
Plone content objects have logic to look up the behaviors' names registered from their types' configuration, the {term}`Factory Type Information` (FTI).
357372
At runtime, the logic provides the interface (or marker) from the behavior to the object.
358373
This dynamically provided interface enables the component architecture to react to this new interface by adding additional form fields, bindings events, enabling more specific views, and more.

0 commit comments

Comments
 (0)