Rename by Title¶
Plone derives the id of a content object from its title only once — when the object is created. Renaming the object later is a separate, manual step.
The Rename by title behavior removes that step: whenever the title of a content object changes, its id (and therefore its URL) is regenerated from the new title.
Behavior¶
When the behavior is active on a content type:
Editing the title through the REST API or the classic edit form renames the object. Editing any other field leaves the id untouched.
The new id is normalized the same way Plone normalizes ids on creation, honouring the editor’s preferred language (
A brand new title→a-brand-new-title).If a sibling already occupies the normalized id, a numbered suffix is appended (
taken-title-1). That suffixed id then stays stable — further edits of the same title do not count the number up.The rename runs with elevated privileges, so an editor who may modify the content but not delete it in its parent folder can still trigger it.
Old URLs keep working: the rename registers a redirect, and requests to the previous URL answer with a redirect to the new one.
Renaming re-validates the container constraints. If the object’s type is not addable in its parent — content created programmatically past the constraints, or a constraint tightened afterwards — the rename is skipped and logged as a warning. The edit itself still goes through.
It does not matter whether title comes from a behavior such as plone.basic
or from a field declared in the type’s own supermodel XML schema.
Staging¶
Working copies are never renamed — their id belongs to the staging mechanism, not to the title. When a working copy is applied, the title is written back to the baseline and the baseline is renamed instead.
REST API¶
Nothing needs to be sent explicitly; the rename is a side effect of changing the title.
await fetch('/Plone/original-title', {
method: 'PATCH',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ title: 'A brand new title' }),
});
// The content now lives at /Plone/a-brand-new-title
const response = await fetch('/Plone/a-brand-new-title', {
headers: { 'Accept': 'application/json' },
});
Requests to the old path are redirected:
import requests
response = requests.get(
'http://localhost:8080/Plone/original-title',
headers={'Accept': 'application/json'},
)
print(response.json()['id']) # a-brand-new-title
Clients that cache content URLs should follow redirects, or re-read the @id
from the response after a title change.
Configuration¶
The behavior is opt-in. To activate it on a content type, add
wcs.backend.content.behaviors.auto_rename.IAutoRename to the FTI’s behaviors
list via GenericSetup:
<object name="MyContentType" meta_type="Dexterity FTI">
<property name="behaviors" purge="false">
<element value="wcs.backend.content.behaviors.auto_rename.IAutoRename"/>
</property>
</object>
Enabling it on an existing site needs an upgrade step importing that profile. Existing objects are not renamed retroactively — their id follows as soon as their title is edited the next time.