Skip to content

Commit 14a6a89

Browse files
committed
improve contet types chapter
1 parent 95bdc65 commit 14a6a89

File tree

4 files changed

+433
-270
lines changed

4 files changed

+433
-270
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
---
2+
myst:
3+
html_meta:
4+
"description": "Creating content types to manage tasks."
5+
"property=og:description": "Creating content ttypes to manage tasks."
6+
"property=og:title": "Creating content types"
7+
"keywords": "Content Types, FTI, Dexterity, plonecli, bobtemplates.plone"
8+
---
9+
10+
# Creating content types
11+
12+
When we attempt to solve a particular content management problem with Plone, we will often design new content types.
13+
For the purpose of this example, we'll build a simple set of types to manage tasks.
14+
15+
- A content type `Tasks` is used to hold all task objects and present a list of tasks to the user.
16+
This type is folderish (Container).
17+
- A content type `Task` with the information about the task.
18+
Fields include name, description, and status of the task.
19+
This type is non-folderish (Item).
20+
21+
## Creating a Plone package
22+
23+
A content type is typically created inside a Plone package. We will use the {term}`plonecli` to create a Plone package and our content types.
24+
25+
```sh
26+
$ plonecli create addon collective.tasks
27+
cd collective.tasks
28+
```
29+
30+
## Adding content types
31+
32+
Let's add a content type called `Tasks`:
33+
34+
```sh
35+
$ plonecli add content_type
36+
```
37+
38+
fill in the name `Tasks` for the first content type:
39+
40+
```sh
41+
-> Content type name (Allowed: _ a-z A-Z and whitespace) [Todo Task]: Tasks
42+
```
43+
44+
we keep the default base class `Container` here:
45+
46+
```sh
47+
--> Dexterity base class (Container/Item) [Container]:
48+
```
49+
50+
we keep the default `globally addable`:
51+
52+
```sh
53+
--> Should the content type globally addable? [y]:
54+
```
55+
56+
we want to filter content types, which can be added to this container:
57+
58+
```sh
59+
--> Should we filter content types to be added to this container? [n]: y
60+
```
61+
62+
we keep the default behaviors active:
63+
64+
```sh
65+
--> Activate default behaviors? [y]:
66+
```
67+
68+
now let's add a content type called `Task`:
69+
70+
```sh
71+
$ plonecli add content_type
72+
```
73+
74+
fill in the name `Task` for the first content type:
75+
76+
```sh
77+
-> Content type name (Allowed: _ a-z A-Z and whitespace) [Todo Task]: Task
78+
```
79+
80+
we change the base class to `Item` here:
81+
82+
```sh
83+
--> Dexterity base class (Container/Item) [Container]: Item
84+
```
85+
86+
we don't want it to be globally addable `globally addable`:
87+
88+
```sh
89+
--> Should the content type globally addable? [y]: n
90+
```
91+
92+
if we disable globally addable, we will be ask a new question, for the parent content type, where we will answer `Tasks`:
93+
94+
```sh
95+
--> Parent container portal_type name: Tasks
96+
```
97+
98+
for the rest of the question we can keep the defaults.
99+
100+
To test our new Plone package and it's content types, we can use {term}`plonecli` to build a development environment and start Plone.
101+
102+
```sh
103+
$ plonecli build
104+
$ plonecli serve
105+
```
106+
107+
Your Plone is now running on http://localhost:8080. You can add a new Plone site, enable your addon and add your content types.
108+
109+
```{note}
110+
{term}`plonecli` takes care of all the details of a content type and it's configuration, for more configuration details see {ref}`backend-content-types-fti-label`.
111+
```
112+
113+
For now your content type don't have any custom schema with fields defined.
114+
115+
See {ref}`backend-schemas-label`, {ref}`backend-fields-label` and {ref}`backend-widgets-label` for information on how to add custom fields and widgets to your content type.
116+
117+
Also have a look at Plone {ref}`backend-behaviors-label`, which provide default features you can enable on per content type basis.

docs/backend/content-types/fti.md

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
---
2+
myst:
3+
html_meta:
4+
"description": "A content type is an object that can store information and is editable by users."
5+
"property=og:description": "A content type is an object that can store information and is editable by users."
6+
"property=og:title": "Factory Type Information (FTI)"
7+
"keywords": "Content Types,FTI"
8+
---
9+
10+
(backend-content-types-fti-label)=
11+
12+
# Factory Type Information (FTI)
13+
14+
A content type is defined by creating a {term}`Factory Type Information` (FTI) object.
15+
16+
To create an FTI in a `GenericSetup` profile, add the content type to the list in `types.xml`.
17+
For example, this adds the standard Plone page (`Document`) content type:
18+
19+
```xml
20+
<object name="portal_types">
21+
<object name="Document" meta_type="Dexterity FTI" />
22+
</object>
23+
```
24+
25+
Then, add a file to the `types` directory with the same name.
26+
In this example, the file is `types/Document.xml` and contains this XML:
27+
28+
```xml
29+
<?xml version="1.0" encoding="utf-8"?>
30+
<object xmlns:i18n="http://xml.zope.org/namespaces/i18n"
31+
meta_type="Dexterity FTI"
32+
name="Document"
33+
i18n:domain="plone"
34+
>
35+
36+
<!-- Basic properties -->
37+
<property name="title"
38+
i18n:translate=""
39+
>Page</property>
40+
<property name="description"
41+
i18n:translate=""
42+
/>
43+
44+
<property name="allow_discussion">False</property>
45+
<property name="factory">Document</property>
46+
<property name="icon_expr">string:contenttype/document</property>
47+
48+
<!-- Hierarchy control -->
49+
<property name="allowed_content_types" />
50+
<property name="filter_content_types">True</property>
51+
<property name="global_allow">True</property>
52+
53+
<!-- Schema, class and security -->
54+
<property name="add_permission">plone.app.contenttypes.addDocument</property>
55+
<property name="klass">plone.app.contenttypes.content.Document</property>
56+
<property name="model_file">plone.app.contenttypes.schema:document.xml</property>
57+
<property name="model_source" />
58+
<property name="schema" />
59+
60+
<!-- Enabled behaviors -->
61+
<property name="behaviors"
62+
purge="false"
63+
>
64+
<element value="plone.namefromtitle" />
65+
<element value="plone.allowdiscussion" />
66+
<element value="plone.excludefromnavigation" />
67+
<element value="plone.shortname" />
68+
<element value="plone.dublincore" />
69+
<element value="plone.richtext" />
70+
<element value="plone.relateditems" />
71+
<element value="plone.versioning" />
72+
<element value="plone.tableofcontents" />
73+
<element value="plone.locking" />
74+
</property>
75+
76+
<!-- View information -->
77+
<property name="add_view_expr">string:${folder_url}/++add++Document</property>
78+
<property name="default_view">document_view</property>
79+
<property name="default_view_fallback">False</property>
80+
<property name="immediate_view">view</property>
81+
<property name="view_methods">
82+
<element value="document_view" />
83+
</property>
84+
85+
<!-- Method aliases -->
86+
<alias from="(Default)"
87+
to="(dynamic view)"
88+
/>
89+
<alias from="edit"
90+
to="@@edit"
91+
/>
92+
<alias from="sharing"
93+
to="@@sharing"
94+
/>
95+
<alias from="view"
96+
to="(selected layout)"
97+
/>
98+
99+
<!-- Actions -->
100+
<action action_id="view"
101+
category="object"
102+
condition_expr=""
103+
icon_expr="string:toolbar-action/view"
104+
title="View"
105+
url_expr="string:${object_url}"
106+
visible="True"
107+
i18n:attributes="title"
108+
>
109+
<permission value="View" />
110+
</action>
111+
<action action_id="edit"
112+
category="object"
113+
condition_expr="not:object/@@plone_lock_info/is_locked_for_current_user|python:True"
114+
icon_expr="string:toolbar-action/edit"
115+
title="Edit"
116+
url_expr="string:${object_url}/edit"
117+
visible="True"
118+
i18n:attributes="title"
119+
>
120+
<permission value="Modify portal content" />
121+
</action>
122+
123+
</object>
124+
```
125+
126+
The `name` attribute on the root element in the XML must match the name in the filename and the name listed in `types.xml`.
127+
128+
Set the `i18n:domain` to the i18n domain which includes translations for this content type.
129+
This is usually the same as the name of the Python package which contains the content type.
130+
131+
132+
(global-fti-properties-label)=
133+
134+
### Global FTI properties
135+
136+
The XML sets a number of FTI properties that are used globally, in both Classic UI and Volto:
137+
138+
`action` elements
139+
: Defines additional {doc}`actions </backend/portal-actions>` which are available for this content type.
140+
141+
`add_permission`
142+
: Id of the permission controlling whether the current user has permission to add this content type.
143+
144+
`allow_discussion`
145+
: Boolean.
146+
Controls whether Plone's commenting system is enabled by default for this content type.
147+
148+
`allowed_content_types`
149+
: List of content types which can be added inside this one.
150+
Only used if `filter_content_types` is True.
151+
152+
`behaviors`
153+
: List of {doc}`behaviors </backend/behaviors>` enabled for this content type.
154+
155+
`description`
156+
: Short description displayed in the UI.
157+
158+
`factory`
159+
: Name of the factory adapter used to create new instances of the content type.
160+
Usually the same as the content type name.
161+
162+
`filter_content_types`
163+
: Boolean.
164+
Controls which content types can be added inside this one.
165+
If `True`, allow only the types listed in `allowed_content_types`.
166+
If `False`, allow any content type that the user has permission to add.
167+
168+
`global_allow`
169+
: Boolean.
170+
Set to `True` to allow adding the content type anywhere in the site where the user has permission.
171+
Set to `False` to only allow adding it inside other content types that include this one in `allowed_content_types`.
172+
173+
`klass`
174+
: Dotted path to the Python class for this content type.
175+
176+
`model_file`
177+
: Location of an XML file to load as the content type's schema.
178+
This is an alternative to `schema` and `model_source`.
179+
180+
`model_source`
181+
: Inline XML schema for the content type.
182+
This is an alternative to `schema` and `model_file`.
183+
184+
`schema`
185+
: Dotted path to the Python schema for this content type.
186+
One of `model_file`, `model_source`, and `schema` must be set.
187+
`schema` is the most commonly used.
188+
189+
`title`
190+
: The name of the content type displayed in the UI.
191+
192+
193+
(classic-ui-only-fti-properties-label)=
194+
195+
### Classic UI only FTI properties
196+
197+
The following FTI properties are used only in Classic UI:
198+
199+
`add_view_expr`
200+
: {term}`TALES` expression returning the URL for the form to add a new item of this content type.
201+
202+
`alias` elements
203+
: Controls a mapping from URL to views.
204+
It's not common to change this.
205+
206+
`default_view`
207+
: Name of the default view used to display this content type.
208+
209+
`default_view_fallback`
210+
: Boolean.
211+
If `True`, the `default_view` will be used if the assigned view is not found.
212+
213+
`icon_expr`
214+
: {term}`TALES` expression returning the name of one of the registered icons.
215+
See {doc}`/classic-ui/icons`.
216+
217+
`immediate_view`
218+
: Name of the view alias to display after a new item is added.
219+
220+
`view_methods`
221+
: List of views which can be selected to display this content type.

0 commit comments

Comments
 (0)