Skip to content

Commit

Permalink
Merge pull request #1461 from plone/classic-ui-forms
Browse files Browse the repository at this point in the history
add classic-ui: forms, fields, schemas, content types
  • Loading branch information
stevepiercy authored Nov 4, 2023
2 parents 8aa79d7 + cfa5485 commit 5aad6cd
Show file tree
Hide file tree
Showing 20 changed files with 1,642 additions and 471 deletions.
12 changes: 6 additions & 6 deletions docs/backend/behaviors.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Other behaviors are implemented as add-on products, which can be installed and c
Once a behavior has been installed, it can be applied to any content type by selecting it in the {guilabel}`Content Types` control panel.
This allows items of this content type to gain the additional functionality provided by the behavior.

A key feature of behaviors is that they allow encapsulating functionality so that it can be reused for multiple content types without needing to reimplement it.
A key feature of behaviors is that they allow encapsulating functionality so that it can be reused for multiple content types without needing to implement it again.
Overall, behaviors are an important part of the Plone content management system and allow for powerful customization and extensibility of content objects.


Expand All @@ -40,7 +40,7 @@ Overall, behaviors are an important part of the Plone content management system

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`.

| short name | Title | Desription |
| short name | Title | Description |
|---|---|---|
| `plone.allowdiscussion` | Allow discussion | Allow discussion on this item |
| `plone.basic` | Basic metadata | Adds title and description fields. |
Expand Down Expand Up @@ -72,11 +72,11 @@ To view a complete list of built-in behaviors, browse to {guilabel}`Content Type
| `volto.preview_image` | Preview Image | Preview image for listings |
| `volto.preview_image_link` | Preview Image Link | Preview image for listings based on links |
| `plone.relateditems` | Related items | Adds the ability to assign related items |
| `plone.richtext` | RichText | Adds richtext behavior |
| `plone.richtext` | RichText | Adds RichText behavior |
| `plone.shortname` | Short name | Gives the ability to rename an item from its edit form. |
| `plone.tableofcontents` | Table of contents | Adds a table of contents |
| `plone.thumb_icon` | Thumbs and icon handling | Options to suppress thumbs and/or icons and to override thumb size in listings, tables etc.
| `plone.versioning` | Versioning | Versioning support with CMFEditions |
| `plone.thumb_icon` | Thumbs and icon handling | Options to suppress thumbs or icons and to override thumb size in listings, tables, and other user interface elements |
| `plone.versioning` | Versioning | Versioning support with `CMFEditions` |

```{todo}
For each behavior in the table above, one may view the source code of the checkbox (its `name` attribute) to view its Short Name.
Expand Down Expand Up @@ -307,7 +307,7 @@ You do not *need* to know this, but it may help if you run into problems.
```

In Plone, behaviors can be globally enabled on content types at runtime.
With add-ons, behaviors can be enabled even on a single content object or for a whole subtree in the content hierarchy.
With add-ons, behaviors can be enabled even on a single content object or for a whole subdirectory tree in the content hierarchy.


### Interfaces and adapters
Expand Down
120 changes: 120 additions & 0 deletions docs/backend/content-types/creating-content-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
myst:
html_meta:
"description": "Creating content types to manage tasks in Plone."
"property=og:description": "Creating content types to manage tasks in Plone."
"property=og:title": "Creating content types to manage tasks in Plone."
"keywords": "Content Types, FTI, Dexterity, plonecli, bobtemplates.plone"
---

# Creating content types

When we attempt to solve a particular content management problem with Plone, we will often design new content types.
For the purpose of this example, we'll build a simple set of types to manage tasks.

- We will use a content type `Tasks` to hold all task objects and present a list of tasks to the user.
This type is folderish (`Container`).
- We will use a content type `Task` with the information about the task.
Fields include name, description, and status of the task.
This type is non-folderish (`Item`).

## Creating a Plone package

We typically create a content type inside a Plone package.
We will use the {term}`plonecli` to create a Plone package and our content types.

```shell
plonecli create addon collective.tasks
cd collective.tasks
```

## Adding content types

Let's add a content type called `Tasks`:

```shell
plonecli add content_type
```

Fill in the name `Tasks` for the first content type:

```console
-> Content type name (Allowed: _ a-z A-Z and whitespace) [Todo Task]: Tasks
```

We keep the default base class `Container` here:

```console
--> Dexterity base class (Container/Item) [Container]:
```

We keep the default `globally addable`:

```console
--> Should the content type globally addable? [y]:
```

We want to filter content types, which can be added to this container:

```console
--> Should we filter content types to be added to this container? [n]: y
```

We keep the default behaviors active:

```console
--> Activate default behaviors? [y]:
```

Now let's add a content type called `Task`:

```shell
plonecli add content_type
```

Fill in the name `Task` for the first content type:

```console
-> Content type name (Allowed: _ a-z A-Z and whitespace) [Todo Task]: Task
```

We change the base class to `Item` here:

```console
--> Dexterity base class (Container/Item) [Container]: Item
```

We don't want it to be globally addable `globally addable`:

```console
--> Should the content type globally addable? [y]: n
```

If we disable `globally addable`, the next question will ask for the parent content type, where we will answer `Tasks`:

```console
--> Parent container portal_type name: Tasks
```

For the rest of the questions, we can keep the defaults.

To test our new Plone package and its content types, we can use {term}`plonecli` to build a development environment and start Plone.

```shell
plonecli build
plonecli serve
```

Your Plone is now running on http://localhost:8080.
You can add a new Plone site, enable your add-on, and add your content types.

```{seealso}
{term}`plonecli` takes care of all the details of a content type and its configuration.
For more configuration details, see {doc}`fti`.
```

For now your content type doesn't have any custom schema with fields defined.

See {doc}`/backend/schemas`, {doc}`/backend/fields` and {doc}`/backend/widgets` for information on how to add custom fields and widgets to your content type.

Also have a look at Plone {doc}`/backend/behaviors`, which provide default features you can enable per content type.
221 changes: 221 additions & 0 deletions docs/backend/content-types/fti.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
---
myst:
html_meta:
"description": "Factory type information (FTI) is responsible for content creation in portals in Plone."
"property=og:description": "Factory type information (FTI) is responsible for content creation in portals in Plone."
"property=og:title": "Factory Type Information (FTI)"
"keywords": "Content Types, FTI"
---

(backend-content-types-fti-label)=

# Factory Type Information (FTI)

A content type is defined by creating a {term}`Factory Type Information` (FTI) object.

To create an FTI in a `GenericSetup` profile, add the content type to the list in `types.xml`.
For example, this adds the standard Plone page (`Document`) content type:

```xml
<object name="portal_types">
<object name="Document" meta_type="Dexterity FTI" />
</object>
```

Then add a file to the `types` directory with the same name.
In this example, the file is `types/Document.xml` and contains this XML:

```xml
<?xml version="1.0" encoding="utf-8"?>
<object xmlns:i18n="http://xml.zope.org/namespaces/i18n"
meta_type="Dexterity FTI"
name="Document"
i18n:domain="plone"
>

<!-- Basic properties -->
<property name="title"
i18n:translate=""
>Page</property>
<property name="description"
i18n:translate=""
/>

<property name="allow_discussion">False</property>
<property name="factory">Document</property>
<property name="icon_expr">string:contenttype/document</property>

<!-- Hierarchy control -->
<property name="allowed_content_types" />
<property name="filter_content_types">True</property>
<property name="global_allow">True</property>

<!-- Schema, class and security -->
<property name="add_permission">plone.app.contenttypes.addDocument</property>
<property name="klass">plone.app.contenttypes.content.Document</property>
<property name="model_file">plone.app.contenttypes.schema:document.xml</property>
<property name="model_source" />
<property name="schema" />

<!-- Enabled behaviors -->
<property name="behaviors"
purge="false"
>
<element value="plone.namefromtitle" />
<element value="plone.allowdiscussion" />
<element value="plone.excludefromnavigation" />
<element value="plone.shortname" />
<element value="plone.dublincore" />
<element value="plone.richtext" />
<element value="plone.relateditems" />
<element value="plone.versioning" />
<element value="plone.tableofcontents" />
<element value="plone.locking" />
</property>

<!-- View information -->
<property name="add_view_expr">string:${folder_url}/++add++Document</property>
<property name="default_view">document_view</property>
<property name="default_view_fallback">False</property>
<property name="immediate_view">view</property>
<property name="view_methods">
<element value="document_view" />
</property>

<!-- Method aliases -->
<alias from="(Default)"
to="(dynamic view)"
/>
<alias from="edit"
to="@@edit"
/>
<alias from="sharing"
to="@@sharing"
/>
<alias from="view"
to="(selected layout)"
/>

<!-- Actions -->
<action action_id="view"
category="object"
condition_expr=""
icon_expr="string:toolbar-action/view"
title="View"
url_expr="string:${object_url}"
visible="True"
i18n:attributes="title"
>
<permission value="View" />
</action>
<action action_id="edit"
category="object"
condition_expr="not:object/@@plone_lock_info/is_locked_for_current_user|python:True"
icon_expr="string:toolbar-action/edit"
title="Edit"
url_expr="string:${object_url}/edit"
visible="True"
i18n:attributes="title"
>
<permission value="Modify portal content" />
</action>

</object>
```

The `name` attribute on the root element in the XML must match the name in the filename and the name listed in `types.xml`.

Set the `i18n:domain` to the i18n domain which includes translations for this content type.
This is usually the same as the name of the Python package which contains the content type.


(global-fti-properties-label)=

## Global FTI properties

The XML sets a number of FTI properties that are used globally, in both Classic UI and Volto:

`action` elements
: Defines additional {doc}`actions </backend/portal-actions>` which are available for this content type.

`add_permission`
: ID of the permission controlling whether the current user has permission to add this content type.

`allow_discussion`
: Boolean.
Controls whether Plone's commenting system is enabled by default for this content type.

`allowed_content_types`
: List of content types which can be added inside this one.
Only used if `filter_content_types` is `True`.

`behaviors`
: List of {doc}`behaviors </backend/behaviors>` enabled for this content type.

`description`
: Short description displayed in the user interface.

`factory`
: Name of the factory adapter used to create new instances of the content type.
Usually the same as the content type name.

`filter_content_types`
: Boolean.
Controls which content types can be added inside this one.
If `True`, allow only the types listed in `allowed_content_types`.
If `False`, allow any content type that the user has permission to add.

`global_allow`
: Boolean.
Set to `True` to allow adding the content type anywhere in the site where the user has permission.
Set to `False` to only allow adding it inside other content types that include this one in `allowed_content_types`.

`klass`
: Dotted path to the Python class for this content type.

`model_file`
: Location of an XML file to load as the content type's schema.
This is an alternative to `schema` and `model_source`.

`model_source`
: Inline XML schema for the content type.
This is an alternative to `schema` and `model_file`.

`schema`
: Dotted path to the Python schema for this content type.
One of `model_file`, `model_source`, and `schema` must be set.
`schema` is the most commonly used.

`title`
: The name of the content type displayed in the user interface.


(classic-ui-only-fti-properties-label)=

## Classic UI only FTI properties

The following FTI properties are used only in Classic UI:

`add_view_expr`
: {term}`TALES` expression returning the URL of the form to add a new item of this content type.

`alias` elements
: Controls a mapping from URL to views.
It's not common to change this.

`default_view`
: Name of the default view used to display this content type.

`default_view_fallback`
: Boolean.
If `True`, the `default_view` will be used if the assigned view is not found.

`icon_expr`
: {term}`TALES` expression returning the name of one of the registered icons.
See {doc}`/classic-ui/icons`.

`immediate_view`
: Name of the view alias to display after a new item is added.

`view_methods`
: List of views which can be selected to display this content type.
Loading

0 comments on commit 5aad6cd

Please sign in to comment.