Skip to main content
Version: Next

Extending Widgets

Widgets are the main building blocks of the perspectives. They can be used to create unique views for the Pimcore Studio.

How to add a custom widget type

To add a custom widget to the Pimcore Studio Backend, you first need to extend the symfony configuration like the following:

Example

pimcore_studio_backend:
widget_types:
- my_custom_widget_id

How to add a custom widget configuration

The widget configuration utilizes the LocationAwareConfigRepository for storing the configuration. In the symfony tree the storage location can be configured. Following values are possible:

  • symfony-config - write configs as Symfony Config as YAML files to /var/config/alternative_object_trees/custom_object_tree.yaml
  • settings-store - write configs to the SettingsStore
  • disabled - do not allow to edit/write configs at all

Details also see Pimcore Docs.

Example

pimcore_studio_backend:
config_location:
element_tree_widgets:
write_target:
type: 'symfony-config'
options:
directory: '/var/www/html/var/config/element_tree_widgets'

To add a custom widget configuration, following steps need to be done:

  1. Create a new custom widget type.
  2. Create a new repository using LocationAwareConfigRepository and implementing the mandatory WidgetConfigRepositoryInterface and register the service with the pimcore.studio_backend.widget_repository tag.
  3. Create a new hydrator which implements the mandatory WidgetConfigHydratorInterface and register the service with the pimcore.studio_backend.widget_hydrator tag.

Restrictions

There are a couple of restrictions and requirements for the widget configuration:

  • Widget configuration name must be longer that 3 and shorter than 80 characters. Furthermore, only alphanumeric characters, underscores and spaces are allowed.
  • Widget configuration ID is autogenerated by Pimcore Studio, based on the UUID generator.
  • Every widget configuration should include at least following properties:
    • id - unique identifier of the widget configuration
    • name - name of the widget configuration
    • icon - icon of the widget (can be nullable, in this case default Icon will be used)
  • When updating a widget, all configuration properties must be present in the PUT request body.

Example Widget Configuration Repository

For an example implementation please have a look at the Pimcore\Bundle\StudioBackendBundle\Perspective\Repository\ElementTreeWidgetConfigRepository file.

Example Widget Configuration Hydrator

<?php
declare(strict_types=1);

namespace App\Perspective\Widget\Hydrator;

use App\Perspective\Widget\Model\CustomWidgetConfig;
use Pimcore\Bundle\StudioBackendBundle\Perspective\Schema\WidgetConfig\WidgetConfigHydratorInterface;

final readonly class CustomWidgetConfigHydrator implements WidgetConfigHydratorInterface
{
public function getSupportedWidgetType(): string
{
return 'my_custom_widget_type';
}

public function hydrate(array $widgetData): CustomWidgetConfig
{
return new CustomWidgetConfig(
$widgetData['id'],
$widgetData['name'],
$widgetData['icon'],
$widgetData['customField'],
$widgetData['createdAt'],
$widgetData['isWriteable']
);
}
}
info

Please note that the Hydrator must return a class extending the Pimcore\Bundle\StudioBackendBundle\Perspective\Schema\WidgetConfig class.

Example Widget Configuration Schema

<?php
declare(strict_types=1);

namespace App\Perspective\Schema;

use Pimcore\Bundle\StudioBackendBundle\Perspective\Schema\WidgetConfig;

#[Schema(
title: 'Custom Widget',
required: [
'customField',
'createdAt',
'isWriteable',
],
type: 'object'
)]
final class MyCustomWidget extends WidgetConfig
{
public function __construct(
string $id,
string $name,
?ElementIcon $icon = null,
#[Property(description: 'Custom Field', type: 'string', example: 'Some Value')]
private readonly string $customField = 'Some Value',
#[Property(description: 'Created At timestamp', type: 'int', example: 1738917191)]
private readonly ?int $createdAt = null,
#[Property(description: 'Is Writeable', type: 'bool', example: false)]
private readonly bool $isWriteable = false,
) {
parent::__construct($id, $name, 'my_custom_widget_type', $icon);
}

public function getCustomField(): string
{
return $this->customField;
}

public function getCreatedAt(): ?int
{
return $this->createdAt;
}

public function isWriteable(): bool
{
return $this->isWriteable;
}
}

Repository and Hydrator will be automatically registered and used by the Pimcore Studio Backend service to handle the widget configuration by defined type.

Example Widget Configuration Yaml

pimcore_studio_backend:
element_tree_widgets:
1efe7ac9_a03a_6334_9e48_13f662882599:
id: 1efe7ac9_a03a_6334_9e48_13f662882599
name: 'My Object Tree Widget'
elementType: 'data-object' # data-object, asset or document types are supported
icon:
type: path
value: 'path/to/config-icon.svg'
rootFolder: '/path/to/root/folder'
showRoot: true
classes: ['CAR']
pql: null # PQL query to filter the tree items
pageSize: 50 # define custom page size for your tree
contextPermissions:
add: true
addFolder: true
changeChildrenSortBy: true
copy: true
cut: true
delete: true
lock: true
lockAndPropagate: true
paste: true
publish: true
reload: true
rename: true
searchAndMove: true
unlock: true
unlockAndPropagate: true
unpublish: true