This extension documentation is published under the
CC BY-NC-SA 4.0
(Creative Commons) license.
This TYPO3 extension adds content planning capabilities to the TYPO3 backend:
assign a status to pages (and other records), assign responsible editors
and leave comments with todos — all directly in the page tree, record list and file list.
Introduction
A quick overview about the main features provided by this extension.
Installation
Instructions on how to install this extension and which TYPO3 and PHP versions are currently supported.
Configuration
Learn how to configure the extension in various ways. This includes extension configuration,
user settings, permission handling and status configuration.
Usage
This section describes the usages of this extension. Learn how to use it the status change,
the interaction possibilities, the console command or using the dashboard.
Developer corner
A quick overview about all relevant classes provided by this extension.
Introduction
What does it do?
This TYPO3 extension adds content planning capabilities to the TYPO3 backend:
assign a status to pages (and other records), assign responsible editors
and leave comments with todos — all directly in the page tree, record list and file list.
Ideal for content migrations, editorial workflows or any process where you need to track
who is working on what.
Colorful, customizable status labels for pages and records.
Change status via page tree, module header, record list or edit form.
Bulk update multiple records at once or via console command.
Enable a Content Planner facet in the page tree filter modal provided by
the optional konradmichalik/typo3-pagetree-facets extension.
Has no effect when that extension is not installed, so the default stays
on: the facet only ever registers once that specific package is present.
Note
Although this defaults to on, it stays off until an administrator
opens Admin Tools > Settings > Extension Configuration
for this extension and saves the form once - a new configuration
key is absent from the saved configuration until then, regardless
of its template default. A value set directly in
$GLOBALS['TYPO3_CONF_VARS'] is not persisted until the form is
saved either. See Pagetree Facets (TYPO3 v13+) for the available filter
tokens.
Assignee
autoAssignment
Type
boolean
Default
1
Enable the auto assignment of the current user when a new status is set to the record.
currentAssigneeHighlight
Type
boolean
Default
1
Enable the current assignee hint to highlight records assigned to the current user.
Records with your user assigned will be highlighted for you in a light yellow color.
Comments
clearCommentsOnStatusReset
Type
boolean
Default
1
Delete corresponding comments when status is reset
commentTodos
Type
boolean
Default
1
Parse the todos from comments and show them as separate hint
Todos from comments
Permissions
Access to the Content Planner functionalities is generally available to all admin users.
All other users require the necessary authorization via the TYPO3 backend permissions module.
Basic Permissions
Via the "Access Rights" tab add one of the following permissions within the Custom module options:
View Only (tx_ximatypo3contentplanner:view-only)
Enables Content Planner visibility (status indicators, comments panel) without any action permissions. Use this in combination with granular permissions.
Full Access (tx_ximatypo3contentplanner:content-status)
Grants visibility and all Content Planner permissions at once. This is useful for power users who should have unrestricted access to all features.
Note
Only users with admin rights or the necessary permissions can access the Content Planner functionalities and can be selected as assignees.
Granular Permissions
In addition to the basic permissions, you can configure granular permissions to control specific actions. These require either View Only or Full Access as a prerequisite for visibility.
Status Permissions
Change Status (tx_ximatypo3contentplanner:status-change)
Allow changing the status of records. Without this permission, users can view status information but cannot modify it.
Unset Status (tx_ximatypo3contentplanner:status-unset)
Allow removing/resetting the status from records. Users without this permission can only set a status, but not clear it.
Comment Permissions
Note
Comment permissions require that users also have Tables (modify) (tables_modify) permission for the Content Planner Comment [tx_ximatypo3contentplanner_comment] table in TYPO3's standard access rights.
Allow deletion of comments created by other users.
Assignment Permissions
Note
Users need at least one assignment permission to edit the assignee field. Without any assignment permission, the assignee field is displayed as read-only.
Allow assigning and unassigning yourself. Users with this permission can use the "Assign to me" shortcut and select themselves from the assignee dropdown. Unassigning is only possible if the record is currently assigned to the user themselves.
Allow assigning, reassigning and unassigning any user. This is a superset of Assign Self - users with this permission can select any user from the assignee dropdown, change existing assignments, and unassign anyone.
Read-Only Fields in Record Editing
When editing records (e.g. page properties), the Content Planner fields are automatically set to read-only if the user lacks the corresponding permission:
Status field: read-only without Change Status permission
Assignee field: read-only without any assignment permission (Assign Self or Assign Others)
Comments field: read-only without Create Comments permission (or missing tables_modify for the comment table)
This ensures that users with View Only access can see the current status, assignee, and comments, but cannot modify them directly in the record form.
Per-Group Restrictions
In addition to the custom module options, you can restrict which statuses and tables a user group can work with:
Allowed Statuses
In the backend user group settings (Content Planner tab), you can specify which statuses are allowed for the group. If left empty, all statuses are available.
Allowed Tables
Similarly, you can restrict which record tables (pages, tt_content, sys_file_metadata, etc.) a group can manage with Content Planner features.
Migration from Previous Versions
If you upgrade from a version without granular permissions, existing user groups with the Content Status permission will continue to work as before - the permission now grants full access.
To use granular permissions:
Use View Only for read-only access or Full Access for unrestricted access
Add the desired fine-grained permissions for each user group
Optionally restrict allowed statuses and tables per group
Tip
If you want to keep the old behavior (full access for all), simply use the Full Access permission. It grants all Content Planner features at once.
Additional Required Permissions
Don't forget to also add the following permissions as well:
"Tables (listing)" (tables_select) and "Tables (modify)" (tables_modify) permissions for the Content Planner Comment [tx_ximatypo3contentplanner_comment] table
All desired dashboard widgets in the "Dashboard widgets" (availableWidgets) permission.
User Settings
The following options can be set in the user settings:
hideContentPlannerStatus
Type
boolean
Default
0
If enabled, the Content Planner status information and colors will be hidden in the TYPO3 backend.
Note
Useful if you have a color overload in the backend or if you don't use the Content Planner status feature.
repliesExpanded
Type
boolean
Default
0
If enabled, threaded replies in the comment modal are expanded by default instead of collapsed.
This setting can also be toggled directly from the comment modal's action menu via the "Expand replies" / "Collapse replies" button.
Usage
This section describes how to properly use the extension in various ways.
By clicking the assignee field in the header bar, a selection dialog will open. This dialog allows you to select a user as assignee for the record. The dialog will show all users with admin rights and the necessary permission.
Select an assignee
Shortcuts
Use the shortcuts beneath the select field for "Assign to me" and "Unassign" to quickly change the assignee.
Assignment shortcuts
Edit Form
The assignee can be selected in the edit form of the record in the "Content Planner" tab.
Every backend user with Content Planner access can add comments to records. Comments are a great way to communicate with other users about the status of a record or to provide additional information.
Use the ToDo list within the editor to track the progress of your comments.
ToDo list in editor
The ToDo count is automatically updated when you add or remove a ToDo item in the comment.
New in version 2.5.0
Click a ToDo checkbox directly in the comment list to check or uncheck it - no need to open
the comment for editing first. This is only available for comments you are allowed to edit.
ToDo count in header
Use the ToDo widget to keep track of your ToDo tasks.
In addition to the ToDos in the comments, there is also the option of marking entire comments as completed, in order to keep the comment list clear and organized.
A comment can be marked as completed via the context menu.
Resolved comments can can be displayed again using the filter
Threaded Replies
New in version 2.2.0
Comments support single-level threaded replies. Each root comment can have replies that are displayed as an indented, collapsible section below it.
Creating replies
Use the Reply action in the comment's dropdown menu or click the reply button at the bottom of the reply list. A reply is created the same way as a regular comment — through the FormEngine modal.
Reply action in the comment dropdown menu
Replies to replies are automatically flattened to a single level (all replies belong to the root comment).
Collapsible section
Replies are collapsed by default. A toggle shows the reply count and the time of the most recent reply (e.g., "3 replies · last 5 minutes ago"). Click the toggle to expand or collapse the reply list.
Expanded reply section with inline reply button
The default expand/collapse behavior can be changed globally via the "Expand replies" / "Collapse replies" button in the comment modal's action menu. This preference is persisted per user. See repliesExpanded in user settings.
Sorting
Root comments are sorted by last activity — either their own creation date or the creation date of their most recent reply, whichever is newer. This means a root comment with a fresh reply automatically moves to the top. The "Newest/Oldest" dropdown controls the sort direction for both root comments and replies.
Comment count
The comment count badge in the page header includes both root comments and replies. This reflects the total discussion activity on a record.
Activity stream & widgets
Replies appear in the activity stream with the label "A new reply comment has been added" and in the comment dashboard widget with a reply badge.
Share links for replies automatically expand the collapse section and scroll to the specific reply.
Share link
New in version 2.1.0
Comments and the entire comment modal can be shared with other backend users via a direct link. The link navigates the recipient to the record, automatically opens the comment modal and, if a specific comment was shared, scrolls to it and briefly highlights it.
Use the context menu of a comment to copy the share link to the clipboard. To share a link to the entire comment modal, use the action menu in the filter bar.
Share a direct link to a comment or the comment modal
Filelist
New in version 2.0.0
Filelist support for files and folders was introduced in version 2.0.
The Content Planner extension supports status management for files and folders in the TYPO3 Filelist module. This allows you to track the status of media assets during content migration or review processes.
Values within one token combine with OR (status:2,3); separate tokens
combine with AND (status:2 assignee:me), same as every other facet in
this filter modal.
Other Registered Records
Other registered records (such as content elements if enabled via
enableContentElementSupport, and
any additional records registered via ExtensionUtility::getRecordTables())
can carry their own status, assignee and comments. However, the page tree
filter only ever returns pages. All three tokens therefore match a page whose
other registered records meet the criteria as well as pages that match
directly, unless the modal's "Pages only" checkbox is ticked, which
restricts every token to page-level matches only. Unticked (the default) is
the broader match.
Files and folders (enableFilelistSupport)
are excluded from this matching, even though they can also carry a status,
assignee and comments: they live in the file storage tree, not the page tree,
and have no page they could resolve to (see "Out of scope" below).
Note
This checkbox defaults to unticked deliberately, not ticked: the filter
modal treats any ticked checkbox across every facet as an active filter
criterion for its chip bar and "N active filters" indicator, with no way
to express "only matters together with another field in this facet" - a
ticked-by-default checkbox would therefore show as a permanent, always-
active chip on every use of the filter modal, regardless of whether any
status, assignee or comment criterion is selected at all.
Note
This checkbox only has an effect once at least one status, assignee or
comment criterion is also selected in this facet — it modifies how those
tokens match, rather than being a filter criterion of its own. With
nothing else selected, the filter modal's underlying framework never
calls this facet at all, so ticking the checkbox alone has nothing to
persist and appears to reset the next time the modal opens.
The Content Planner (Configurable) widget is a powerful, customizable widget.
It allows you to create multiple instances with different configurations, each tailored to your specific needs.
Settings
The widget can be configured through the widget settings dialog:
Widget settings dialog with all available filter options
Setting:
Description:
Custom Title
Set a custom title for the widget. If left empty, an automatic title based on the selected mode will be used.
Display Mode
Choose what kind of records to display:
All Status Records: Shows all records with any content planner status
Assigned Records: Shows records filtered by assignee
Records with open TODOs: Shows only records that have open tasks in their comments
Status Filter
Filter records by a specific status. Select "All statuses" to show records with any status.
Assignee Filter
Filter records by assignee:
All assignees: No assignee filter
Current User: Shows only records assigned to the logged-in user
Specific user: Select a specific backend user
Record Type Filter
Filter records by table type (e.g., pages, news, etc.). Select "All record types" to show all registered tables.
Use Cases
Here are some example configurations:
Personal Task List
Set "Display Mode" to "Assigned Records" and "Assignee Filter" to "Current User" with a custom title like "My Tasks".
Review Queue
Set "Status Filter" to your "In Review" status to create a dedicated review queue widget.
Open TODOs Overview
Set "Display Mode" to "Records with open TODOs" to track all unfinished tasks across the project.
News Articles Status
Set "Record Type Filter" to "News" to monitor only news article statuses.
Command
The extension provides the following console commands:
content-planner:bulk-update
A command to update multiple records based on a given configuration.
For folders, use the combined identifier instead of a numeric uid.
The combined identifier consists of the storage uid and the folder path,
separated by a colon (e.g., 1:/user_upload/myfolder/).
Many of the content planner processes are configurable or can be extended
with custom implementations. This section provides an insight into
which development options are available and how these can be integrated
into the status process.
By default the Content Planner supports the status functionality only for pages. If you want to use the status functionality for other record types, you can extend the Content Planner to support additional record types.
Categories as additional records
Note
Keep in mind to consider the loading order of the Content Planner extension. If you want to use the Content Planner for additional records, you need to load the Content Planner extension before the extension that provides the additional records.
Follow the steps below to extend the Content Planner to support additional records, e.g. news or tt_content records:
Extend the additional record TCA (e.g. for news records):
The extension contains some PSR-14 events which make it possible to extend the extension with own functionality.
You can for example adjust the status selection or react on status changes for implementing some kind of a workflow.
This event is dispatched after the status of a record has been changed. You can use it to trigger additional actions like notifications or workflow transitions.
Note that $newStatus may be null when a status is cleared from a record.
Classes/EventListener/StatusChangeListener.php
<?phpnamespaceMyVendor\MyExtension\EventListener;
useXima\XimaTypo3ContentPlanner\Event\StatusChangeEvent;
finalclassStatusChangeListener{
publicfunction__invoke(StatusChangeEvent $event): void{
$table = $event->getTable();
$uid = $event->getUid();
$newStatus = $event->getNewStatus();
$previousStatus = $event->getPreviousStatus();
// Example: Send notification when status changes to a specific status (uid 3)if ($newStatus?->getUid() === 3) {
// Trigger notification logic
}
}
}
This event is dispatched after a new comment has been saved to the database. This includes both root comments and replies. Use it for notifications, activity logging, or integration with external systems.
The table property refers to the record being commented on (e.g. pages), not the comment table itself.
<?phpnamespaceMyVendor\MyExtension\EventListener;
useXima\XimaTypo3ContentPlanner\Event\CommentCreatedEvent;
finalclassCommentNotificationListener{
publicfunction__invoke(CommentCreatedEvent $event): void{
$table = $event->getTable(); // e.g. 'pages'
$recordUid = $event->getRecordUid(); // UID of the commented record
$commentUid = $event->getCommentUid(); // UID of the new comment
$authorUid = $event->getAuthorUid(); // UID of the backend user// Example: Send Slack notification
}
}
The
ExtensionUtility
is the public API for TCA configuration and feature
management. Use it to register additional record tables (see
Additional Records) and to query the current extension configuration
from your own code.
Utility class for TCA configuration and feature management.
addContentPlannerTabToTCA($table)
Add the "Content Planner" tab (status, assignee and comments palette) to
the TCA of the given table. Call this in a
Configuration/TCA/Overrides/<table>.php file.
param string $table
Table name to extend.
returntype
void
getRecordTables()
Get all tables that are tracked by the content planner. Includes
pages
, the optionally enabled
tt_content
and filelist
tables as well as all tables registered via
registerAdditionalRecordTables
.
returntype
string[]
isRegisteredRecordTable($table)
Check whether the given table is tracked by the content planner.
param string $table
Table name to check.
returntype
bool
isFilelistSupportEnabled()
Check whether filelist support (files and folders) is enabled via the
enableFilelistSupport extension
configuration.
returntype
bool
isContentElementSupportEnabled()
Check whether content element support (
tt_content
) is enabled via
the enableContentElementSupport
extension configuration.
returntype
bool
isFeatureEnabled($feature)
Check whether a boolean extension configuration feature is enabled.
param string $feature
Configuration key, e.g. commentTodos.
returntype
bool
getExtensionSetting($feature)
Get the raw value of an extension configuration option as string.
Optional user object, UID or username of the author.
param int $parentUid
UID of the parent comment to reply to. Must belong to the same record, otherwise an
\InvalidArgumentException
is thrown. 0 creates a top-level comment. If it identifies an existing reply rather than a root comment, the new comment is attached to that reply's root comment instead.
returntype
void
generateTodoForComment($todos)
Simple function to generate the html todo markup for a comment to easily insert them into the comment content.
param array $todos
Array of todo strings.
returntype
string
clearCommentsOfRecord($table, $uid, $like = null)
Simple function to clear all comment(s) of a content planner record.
param string $table
Table name of the record.
param int $uid
UID of the record.
param string|null $like
Optional string to filter comments by content.
returntype
void
hasComments($record)
Simple function to check whether a record has comments.
param array $record
Record array containing the content planner comment counter field.