Additional and Custom Attributes
Every API response schema implements AdditionalAttributesInterface (via AdditionalAttributesTrait),
which lets you attach arbitrary key-value data to any response.
Custom attributes are a specialized subset for tree and editor customization (icons, tooltips,
CSS classes). They are available on tree response schemas by default. To add custom attributes to
other schemas, implement CustomAttributesTrait in the schema class.
Adding Attributes via Events
Each schema dispatches its own PreResponse event before the response is sent.
Subscribe to the event for the schema you want to enrich. All events extend
AbstractPreResponseEvent, which provides methods to add additional attributes and
a type-safe getter for the underlying schema object.
Subscribing to Events
For the subscriber pattern, see Extending via Events.
Example: PreResponse Event Structure
<?php
declare(strict_types=1);
namespace App\Asset\Event\PreResponse;
use Pimcore\Bundle\StudioBackendBundle\Asset\Schema\Asset;
use Pimcore\Bundle\StudioBackendBundle\Element\Schema\CustomAttributes;
use Pimcore\Bundle\StudioBackendBundle\Event\AbstractPreResponseEvent;
final class AssetEvent extends AbstractPreResponseEvent
{
public const EVENT_NAME = 'pre_response.asset';
public function __construct(
private readonly Asset $asset
) {
parent::__construct($asset);
}
/**
* Use this to get additional infos out of the response object
*/
public function getAsset(): Asset
{
return $this->asset;
}
public function getCustomAttributes(): CustomAttributes
{
return $this->asset->getCustomAttributes();
}
public function setCustomAttributes(CustomAttributes $customAttributes): void
{
$this->asset->setCustomAttributes($customAttributes);
}
}
Custom Icons & Tooltips
A common use of custom attributes is overriding the icon and tooltip shown in the element tree and editor tabs. The following subscriber sets a custom icon and tooltip for all Data Objects of class "Car":
Note: The tree and editor/detail endpoints fire separate events. To customize icons in both the tree and editor tabs, subscribe to both
pre_response.data_object(tree) andpre_response.data_object_detail(editor). See the Custom Icons & Tooltips extension guide for a complete example.
<?php
declare(strict_types=1);
namespace App\EventSubscriber;
use Pimcore\Bundle\StudioBackendBundle\DataObject\Event\PreResponse\DataObjectEvent;
use Pimcore\Bundle\StudioBackendBundle\Response\ElementIcon;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementIconTypes;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CarTreeStyleSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
DataObjectEvent::EVENT_NAME => 'handleDataObject',
];
}
public function handleDataObject(DataObjectEvent $event): void
{
$dataObject = $event->getDataObject();
if ($dataObject->getClassName() !== 'Car') {
return;
}
$customAttributes = $event->getCustomAttributes();
// Named icon from the Studio icon set
$customAttributes->setIcon(
new ElementIcon(ElementIconTypes::NAME->value, 'car')
);
// Or use a path to a custom SVG:
// $customAttributes->setIcon(
// new ElementIcon(ElementIconTypes::PATH->value, '/static/images/icons/car.svg')
// );
$customAttributes->setTooltip(
'<b>' . htmlspecialchars($dataObject->getKey()) . '</b><br>ID: ' . $dataObject->getId()
);
$event->setCustomAttributes($customAttributes);
}
}
For more details and frontend customization options, see the Custom Icons & Tooltips extension guide.
List of custom attributes
icon- The custom icon that should be displayed in the tree.tooltip- The custom HTML tooltip to be displayed in the tree.additionalIcons- Array of additional icons that should be displayed in the tree.key- The key that should be displayed in the tree.additionalCssClasses- Additional CSS classes that should be added to the tree element.
List of available events
asset.deletedata_object.deletedocument.deletepre_response.all_layouts.collectionpre_response.assetpre_response.asset_custom_metadatapre_response.asset_custom_settingspre_response.asset_predefined_metadatapre_response.asset_typepre_response.asset_versionpre_response.asset.video_typepre_response.bundle_application_logger.listpre_response.bundle_seo.redirect.import_statspre_response.bundle_seo.redirect.listpre_response.bundle_seo.redirect.statuspre_response.bundle_seo.robots_txt_configpre_response.class.bulk_export_available_itempre_response.class.bulk_import_preparepre_response.class.bulk_import_result_itempre_response.class_definitionpre_response.class_definition.visible_fieldpre_response.class_definition.collectionpre_response.class_definition.folder.collectionpre_response.class_definition.identifier_datapre_response.class_definition.object_brick_datapre_response.class_definition.object_brick_fieldpre_response.class_definition.treepre_response.class_field_by_typepre_response.classification_store.collectionpre_response.classification_store.config_collectionpre_response.classification_store.configuration.collectionpre_response.classification_store.configuration.collection_relationpre_response.classification_store.configuration.get_pagepre_response.classification_store.configuration.grouppre_response.classification_store.configuration.keypre_response.classification_store.configuration.key_group_relationpre_response.classification_store.configuration.storepre_response.classification_store.configuration.store_tree_nodepre_response.classification_store.grouppre_response.classification_store.group_layoutpre_response.classification_store.key_group_relationpre_response.custom_layoutpre_response.custom_layout.collectionpre_response.custom_layout.identifier_datapre_response.custom_report_chart_datapre_response.custom_report_reportpre_response.custom_report_tree_config_nodepre_response.custom_report_tree_nodepre_response.custom_report.column_informationpre_response.data_objectpre_response.data_object_detailpre_response.data_object.dynamic_select_optionpre_response.data_object.formated_pathpre_response.data_object.layoutpre_response.data_object.preview_config_entrypre_response.data_object_versionpre_response.dependencypre_response.documentpre_response.document_typepre_response.document.doc_typepre_response.document.doc_type.typepre_response.document.get_translationspre_response.document.get_translation;parentpre_response.document.list_available_controllerspre_response.document.list_available_templatespre_response.document.page-snippet.render-area-block-editmodepre_response.document.site.detailpre_response.document.sites_list_availablepre_response.document_versionpre_response.email.blocklist.entrypre_response.email.log.detailpre_response.email.log.detail.paramspre_response.email.logList.entrypre_response.element.context_permissionspre_response.element_editLockpre_response.element_locatepre_response.element_propertypre_response.element_subtypepre_response.execution_engine.list_running_job_runspre_response.field_collection.configpre_response.field_collection.config_layout_definitionpre_response.field_collection.detailpre_response.field_collection.layout_definitionpre_response.field_collection.treepre_response.field_collection.usage_datapre_response.grid_column_configurationpre_response.grid_column_datapre_response.grid_configurationpre_response.grid_detailed_configurationpre_response.list_thumbnailpre_response.notificationpre_response.notification.list.itempre_response.notepre_response.note.typepre_response.objectBrick.configpre_response.objectBrick.config_layout_definitionpre_response.objectBrick.detailpre_response.objectBrick.layout_definitionpre_response.objectBrick.treepre_response.objectBrick.usage_datapre_response.perspective.config.getpre_response.perspective.widget.config.getpre_response.perspective.widget.typepre_response.predefined_propertypre_response.quantity_value.unit.conversion_collectionpre_response.quantity_value.unit_listpre_response.recycle_bin.itempre_response.role_tree_nodepre_response.saved_search_configuration_list_itempre_response.saved_search_configurationpre_response.saved_search_detailed_configurationpre_response.schedulepre_response.schedule.action_typepre_response.select_option.detailpre_response.select_option.treepre_response.select_option.usage_itempre_response.settings.active_bundlepre_response.settings.available_countrypre_response.simple_search.previewpre_response.simple_search.resultpre_response.simple_userpre_response.tagpre_response.thumbnail.image_configpre_response.thumbnail.image_config_detailpre_response.thumbnail.image_folderpre_response.thumbnail.video_configpre_response.thumbnail.video_config_detailpre_response.thumbnail.video_folderpre_response.translationspre_response.translations.import.csv-settingspre_response.userpre_response.user_detailed_rolepre_response.user_informationpre_response.user_permissionpre_response.user_simple_rolepre_response.user_tree_nodepre_response.versionpre_response.website_settings.itempre_response.workflow_elementpre_response.workflow_detailspre_response.notification_recipientpre_response.php_code_transformerpre_response.data_providerpre_response.gdpr_data_rowpre_response.data_providerpre_response.element.usage.itempre_response.element.usage