Skip to main content
Version: 2026.3

Custom Icons and Tooltips in the Element Tree and Editor Tabs

Customize how elements appear in the tree and editor tabs by overriding their icon and tooltip via backend event subscribers. The Studio UI renders these customizations automatically; no frontend plugin code is needed for basic cases.

Custom Attributes​

The CustomAttributes schema on every tree response supports these fields:

FieldTypeRendered in tree?
iconElementIcon (type + value)Yes
tooltipstring (HTML)Yes (on hover)
additionalIconsstring[]Not yet
keystringNot yet
additionalCssClassesstring[]Not yet

The icon field accepts an ElementIcon with two properties:

  • type: Either 'name' (a named icon from the Studio icon set) or 'path' (URL path to a custom SVG/image).
  • value: The icon name or path.

How to Override: Backend Event Subscriber​

Subscribe to pre_response.* events to modify the CustomAttributes before the response is sent to the frontend. Each element type has its own event:

Element typeContextEvent nameEvent class
Data ObjectTreepre_response.data_objectDataObjectEvent
Data ObjectEditor tabpre_response.data_object_detailDataObjectDetailEvent
AssetTreepre_response.assetAssetEvent
DocumentTreepre_response.documentDocumentEvent

Important: To customize the icon everywhere (tree and editor tabs), subscribe to both the tree event and the detail event. The tree endpoint and the detail/editor endpoint fire separate events.

Example: Custom Icon and Tooltip for Data Objects (Tree and Editor Tabs)​

This subscriber sets a flag icon and an HTML tooltip for all objects of class "Demo", in both the tree and the editor tab:

<?php
declare(strict_types=1);

namespace App\EventSubscriber;

use Pimcore\Bundle\StudioBackendBundle\DataObject\Event\PreResponse\DataObjectDetailEvent;
use Pimcore\Bundle\StudioBackendBundle\DataObject\Event\PreResponse\DataObjectEvent;
use Pimcore\Bundle\StudioBackendBundle\Element\Schema\CustomAttributes;
use Pimcore\Bundle\StudioBackendBundle\Response\ElementIcon;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementIconTypes;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class CustomTreeStyleSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
DataObjectEvent::EVENT_NAME => 'handleDataObject',
DataObjectDetailEvent::EVENT_NAME => 'handleDataObjectDetail',
];
}

public function handleDataObject(DataObjectEvent $event): void
{
$dataObject = $event->getDataObject();

if ($dataObject->getClassName() !== 'Demo') {
return;
}

$this->applyDemoStyle($event->getCustomAttributes(), $dataObject->getId());
$event->setCustomAttributes($event->getCustomAttributes());
}

public function handleDataObjectDetail(DataObjectDetailEvent $event): void
{
$dataObject = $event->getDataObject();

if ($dataObject->getClassName() !== 'Demo') {
return;
}

$this->applyDemoStyle($event->getCustomAttributes(), $dataObject->getId());
$event->setCustomAttributes($event->getCustomAttributes());
}

private function applyDemoStyle(CustomAttributes $customAttributes, int $id): void
{
// Use a named icon from the Studio icon set
$customAttributes->setIcon(
new ElementIcon(
ElementIconTypes::NAME->value,
'flag'
)
);

// HTML tooltip shown on hover in the tree
$customAttributes->setTooltip(
'<b>Demo Object</b><br>ID: ' . $id
);
}
}

With autoconfigure: true in your services.yaml, the subscriber is automatically registered. No manual tag needed.

Example: Custom Icon for Assets​

This subscriber sets a star icon for all assets whose filename starts with important_:

<?php
declare(strict_types=1);

namespace App\EventSubscriber;

use Pimcore\Bundle\StudioBackendBundle\Asset\Event\PreResponse\AssetEvent;
use Pimcore\Bundle\StudioBackendBundle\Response\ElementIcon;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementIconTypes;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class CustomAssetStyleSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
AssetEvent::EVENT_NAME => 'handleAsset',
];
}

public function handleAsset(AssetEvent $event): void
{
$asset = $event->getAsset();

if (!str_starts_with($asset->getFilename(), 'important_')) {
return;
}

$customAttributes = $event->getCustomAttributes();

$customAttributes->setIcon(
new ElementIcon(
ElementIconTypes::NAME->value,
'star'
)
);

$customAttributes->setTooltip(
'<b>' . htmlspecialchars($asset->getFilename()) . '</b>'
. '<br>Type: ' . $asset->getType()
);

$event->setCustomAttributes($customAttributes);
}
}

For a full list of available pre_response.* events, see Additional and Custom Attributes.