Widgets need to be provided by an extension, e.g. by ext:dashboard. They are provided as a PHP class with specific feature sets. Each of the widgets can be registered with different configurations as documented below.
Note
Difference between registration of widgets and implementation of widgets:
Widgets provide some functionality, e.g. collect system log errors over a time span.
This functionality is provided by the implementation, a PHP class with some code.
The registration is done in Services.
,
in order to create the actual widget with provided functionality.
During registration options can be set, e.g. the time span.
Registration is documented at Register new Widget, while implementation is documented at Implement new widget.
The below example will use the RSS Widget as a concrete example.
Register new Widget
Registration happens through Dependency Injection
either in Services.
or Services.
.
Both files can exist and will be merged.
Services.
is recommended and easier to write,
while Services.
provide way more flexibility.
Naming widgets
Widgets receive a name in form of dashboard.widget.vendor.ext_key.widgetName
.
vendor
- Should be a snaked version of composer vendor.
ext_key
- Should be the extension key.
This prevents naming conflicts if multiple 3rd Party extensions are installed.
Services.yaml File
In order to turn the PHP class \TYPO3\
into an actual widget,
the following service registration can be used:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
TYPO3\CMS\Dashboard\:
resource: '../Classes/*'
dashboard.widget.t3news:
class: 'TYPO3\CMS\Dashboard\Widgets\RssWidget'
arguments:
$view: '@dashboard.views.widget'
$buttonProvider: '@dashboard.buttons.t3news'
$cache: '@cache.dashboard.rss'
$options:
feedUrl: 'https://www.typo3.org/rss'
tags:
- name: dashboard.widget
identifier: 't3news'
groupNames: 'news'
title: 'LLL:EXT:dashboard/Resources/Private/Language/locallang.xlf:widgets.t3news.title'
description: 'LLL:EXT:dashboard/Resources/Private/Language/locallang.xlf:widgets.t3news.description'
iconIdentifier: 'content-widget-rss'
height: 'large'
width: 'medium'
The beginning of the file is not related to the widget itself, but dependency injection in general, see: Configuration.
Service configuration
The last block configured a service called dashboard.
.
This service is configured to use the existing PHP class \TYPO3\
.
When creating the instance of this class, an array is provided for the constructor argument $options
.
This way the same PHP class can be used with different configuration to create new widgets.
The following keys are defined for the service:
class
-
- Type
- string
- Example
\TYPO3\
CMS\ Dashboard\ Widgets\ Rss Widget
Defines the concrete PHP class to use as the implementation of the widget.
arguments
-
- Type
- map
A set of key-value pairs, where the keys are the argument names and the values are the corresponding argument values. The specific arguments depend on the widget being configured, and each widget can define custom arguments.
Documentation for the provided widgets is available at Widgets.
tags
-
- Type
- array of dictionaries
Registers the service as an actual widget for typo3/cms-dashboard . Each entry in the array is a dictionary that can include various properties like name, identifier, groupNames, and so on, used to categorize and identify the widget.
See Tags Section.
Tags Section
In order to turn the instance into a widget, the tag dashboard.
is configured in tags
section.
The following options are mandatory and need to be provided:
name
-
- Type
- string
- Required
true
- Example
dashboard.
widget
Always has to be
dashboard.
. Defines that this tag configures the service to be registered as a widget for ext:dashboard.widget
identifier
-
- Type
- string
- Required
true
- Example
t3news
Used to store which widgets are currently assigned to dashboards. Furthermore, it is used to allow access control, see Permissions of widgets.
groupNames
-
- Type
- string (comma-separated)
- Required
true
- Example
news
Defines which groups should contain the widget. Used when adding widgets to a dashboard to group related widgets in tabs. Multiple names can be defined as a comma-separated string, e.g.:
typo3, general
.See Create widget group regarding how to create new widget groups. There is no difference between custom groups and existing groups. Widgets are registered to all groups by their name.
title
-
- Type
- string (language reference)
- Required
true
- Example
LLL:
EXT: dashboard/ Resources/ Private/ Language/ locallang. xlf: widgets. t3news. title
Defines the title of the widget. Language references are resolved.
description
-
- Type
- string (language reference)
- Required
true
- Example
LLL:
EXT: dashboard/ Resources/ Private/ Language/ locallang. xlf: widgets. t3news. description
Defines the description of the widget. Language references are resolved.
iconIdentifier
-
- Type
- string
- Required
true
- Example
content-
widget- rss
One of the registered icons. Icons can be registered through Icon API.
The following options are optional and have default values which will be used if not defined:
height
-
- Type
- string
- Example
large
Has to be a string value:
large
,medium
, orsmall
.
width
-
- Type
- string
- Example
medium
Has to be a string value:
large
,medium
, orsmall
.
additionalCssClasses
-
- Type
- string
Will be added to the surrounding rendered markup. Usually used when working with Graphs.
Splitting up Services.yaml
In case the Services.
is getting to large, it can be split up.
The official documentation can be found at symfony.com.
An example to split up all Widget related configuration would look like:
imports:
- { resource: Backend/DashboardWidgets.yaml }
Note
Note that you have to repeat all necessary information, e.g. services:
section with _defaults:
again.
services:
_defaults:
autowire: true
autoconfigure: true
public: false
TYPO3\CMS\Dashboard\Widgets\:
resource: '../Classes/Widgets/*'
dashboard.buttons.t3news:
class: 'TYPO3\CMS\Dashboard\Widgets\Provider\ButtonProvider'
arguments:
$title: 'LLL:EXT:dashboard/Resources/Private/Language/locallang.xlf:widgets.t3news.moreItems'
$link: 'https://typo3.org/project/news'
$target: '_blank'
dashboard.widget.t3news:
class: 'TYPO3\CMS\Dashboard\Widgets\RssWidget'
arguments:
$view: '@dashboard.views.widget'
$buttonProvider: '@dashboard.buttons.t3news'
$cache: '@cache.dashboard.rss'
$options:
feedUrl: 'https://www.typo3.org/rss'
tags:
- name: dashboard.widget
identifier: 't3news'
groupNames: 'news'
title: 'LLL:EXT:dashboard/Resources/Private/Language/locallang.xlf:widgets.t3news.title'
description: 'LLL:EXT:dashboard/Resources/Private/Language/locallang.xlf:widgets.t3news.description'
iconIdentifier: 'content-widget-rss'
height: 'large'
width: 'medium'
Services.php File
This is not intended for integrators but developers only, as this involves PHP experience.
The typical use case should be solved via Services.
.
But for more complex situations, it is possible to register widgets via Services.
.
Even if Services.
contains PHP, it is only executed during compilation of the dependency injection container.
Therefore, it is not possible to check for runtime information like URLs, users, configuration or packages.
Instead, this approach can be used to register widgets only if their service dependencies are available.
The Container
instance provides a method has
that may be used to check for optional dependencies.
Make sure to declare the optional dependencies in composer.
and ext_
as
suggested extensions to ensure packages are ordered correctly in order for
services to be registered with deterministic ordering.
The following example demonstrates how a widget can be registered via Services.
:
<?php
declare(strict_types=1);
namespace Vendor\ExtName;
use Vendor\ExtName\Widgets\ExampleWidget;
use Vendor\ExtName\Widgets\Provider\ExampleProvider;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\DependencyInjection\Reference;
use TYPO3\CMS\Report\Status;
return function (ContainerConfigurator $configurator, ContainerBuilder $containerBuilder) {
$services = $configurator->services();
if ($containerBuilder->hasDefinition(Status::class)) {
$services->set('widgets.dashboard.widget.exampleWidget')
->class(ExampleWidget::class)
->arg('$view', new Reference('dashboard.views.widget'))
->arg('$buttonProvider', new Reference(ExampleProvider::class))
->arg('$options', ['template' => 'Widget/ExampleWidget'])
->tag('dashboard.widget', [
'identifier' => 'widgets-exampleWidget',
'groupNames' => 'systemInfo',
'title' => 'LLL:EXT:ext_key/Resources/Private/Language/locallang.xlf:widgets.dashboard.widget.exampleWidget.title',
'description' => 'LLL:EXT:ext_key/Resources/Private/Language/locallang.xlf:widgets.dashboard.widget.exampleWidget.description',
'iconIdentifier' => 'content-widget-list',
'height' => 'medium',
'width' => 'medium'
])
;
}
};
Above example will register a new widget called widgets.dashboard.widget.exampleWidget
.
The widget is only registered, in case the extension "reports" is enabled, which
results in the availablity of the \TYPO3\
during container compile time.
Configuration is done in the same way as with Services.
, except a PHP API is used.
The new Reference
equals to @
inside the YAML, to reference another service.
arguments:
are registered via ->arg
method call.
And tags:
are added via ->tag
method call.
Using this approach, it is possible to provide widgets that depend on 3rd party code, without requiring this 3rd party code. Instead the 3rd party code can be suggested and is supported if its installed.
Further information regarding how Services.
works in general, can be found
at symfony.com.
Make sure to switch code examples from YAML to PHP.