Skip to main content Skills Marktplatz Entdecken und erkunden Sie KI-Skills, die von der Community erstellt wurden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Prompt kopierenPrompt-Details anzeigen Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
npx skills add https://github.com/pimcore/skills --skill pimcore-studio-ui-navigationDer Befehl bleibt in einer Zeile. Scrollen Sie horizontal, um ihn vor dem Kopieren vollständig zu prüfen.
Sie bevorzugen eine lokale Kopie? Laden Sie die Dateien herunter, die SkillsMP derzeit vorliegen.
ZIP herunterladen Herunterladen... Mehr aus diesem Repository
pimcore-studio-ui-filters Building filters in Pimcore Studio UI - the declarative defineFilter framework for filter panels and sidebars (createFiltersStore, FiltersRenderer, useFilterQuery) and custom field-filter dynamic types for per-column listing filters (DynamicTypeFieldFilterAbstract, DynamicTypeFieldFilterRegistry). Use this whenever building, customizing, or extending any kind of filtering, filter panel, filter sidebar, or search/filter UI, or adding a new filter type to a listing or data view - even when the user only says "add filtering", "let users filter by X", "filter this list", or "build a filter sidebar".
Verwandte Berufe SOC
Basierend auf der SOC-Berufsklassifikation
name pimcore-studio-ui-navigation description Adding main navigation entries and perspective permissions in Pimcore Studio UI - frontend registration and backend permission management metadata {"audience":"pimcore-developers","focus":"navigation-perspectives"}
What This Skill Covers
How to add navigation entries to Pimcore Studio UI with perspective permissions:
Registering main navigation items (frontend)
perspectivePermission field and relation to perspectives
Backend perspective permission registration (PHP)
StudioContextPermissionsSubscriber pattern
Translation keys for navigation and perspective editor
Permission groups and naming conventions
When to Use This Skill
Use this when:
Adding new features that need main navigation entries
Creating bundle navigation items
Setting up perspective permissions for features
Controlling feature visibility per perspective
Adding menu items to the sidebar
Writing Style for Navigation Labels
Navigation items use Title Case - each principal word is capitalized.
This applies to:
Main navigation menu items
Tab titles when menu items are opened
Context menu labels
Section headings
Widget titles
Title Case Examples
mainNavRegistry.registerMainNavItem ({
path : ,
:
})
'Data Management/Custom Reports'
label
'custom-reports.title'
Navigation vs Buttons Element Type Case Style Example Navigation items Title Case "Custom Reports" Menu items Title Case "Output Channels" Tab titles Title Case "Data Objects" Buttons Sentence case "Export CSV" Actions Sentence case "Save draft"
Remember: Navigation = Title Case, Buttons/Actions = Sentence case
🚨 Import Paths All examples below use bundle imports (@pimcore/studio-ui-bundle/*). For core development (@sdk/*, @Pimcore/*), see the referenced file.
Navigation Registration (Frontend) Navigation items are registered in your module's initialization file using the MainNavRegistry .
Basic Pattern
import { type AbstractModule } from '@pimcore/studio-ui-bundle'
import { container, serviceIds } from '@pimcore/studio-ui-bundle/app'
import { type MainNavRegistry } from '@pimcore/studio-ui-bundle/modules/app'
export const YourFeatureModule : AbstractModule = {
onInit : (): void => {
const mainNavRegistry = container.get <MainNavRegistry >(serviceIds.mainNavRegistry )
mainNavRegistry.registerMainNavItem ({
path : 'ParentGroup/SubGroup/Your Feature' ,
label : 'your-feature.navigation.title' ,
order : 5 ,
perspectivePermission : 'dataManagement.yourFeature' ,
widgetConfig : {
name : 'Your Feature' ,
id : 'your-feature' ,
component : 'your-feature' ,
config : {
translationKey : 'your-feature.navigation.title' ,
icon : {
type : 'name' ,
value : 'your-icon'
}
}
}
})
}
}
Navigation Item Properties interface IMainNavItem {
path : string
label ?: string
order ?: number
perspectivePermission ?: string
widgetConfig ?: WidgetManagerTabConfig
id ?: string
icon ?: string
groupIcon ?: string
group ?: string
dividerBottom ?: boolean
children ?: IMainNavItem []
permission ?: string
perspectivePermissionHide ?: string
className ?: string
hidden ?: () => boolean
}
Real-World Example: Target Groups
export const TargetGroupsModule : AbstractModule = {
onInit : (): void => {
const mainNavRegistry = container.get <MainNavRegistry >(serviceIds.mainNavRegistry )
mainNavRegistry.registerMainNavItem ({
path : 'ExperienceEcommerce/PersonalisationTargeting/Target Groups' ,
label : 'personalization.target-groups' ,
order : 10 ,
permission : 'targeting' ,
perspectivePermission : 'experienceEcommerce.personalizationTargetGroups' ,
widgetConfig : {
name : 'Target Groups' ,
id : 'target-groups' ,
component : 'target-groups-container' ,
config : {
translationKey : 'personalization.target-groups' ,
icon : {
type : 'name' ,
value : 'target-group'
}
}
}
})
}
}
perspectivePermission Field The perspectivePermission field controls which perspectives can see the navigation item.
Format: Dot Notation perspectivePermission: '{group}.{permissionKey}'
First part: Group name (must match ContextPermissionGroups enum)
Second part: Permission key (registered in PHP)
Available Permission Groups
enum ContextPermissionGroups : string
{
case QUICK_ACCESS = 'quickAccess' ;
case DATA_MANAGEMENT = 'dataManagement' ;
case EXPERIENCE_ECOMMERCE = 'experienceEcommerce' ;
case ASSET_MANAGEMENT = 'assetManagement' ;
case TRANSLATIONS = 'translations' ;
case REPORTING = 'reporting' ;
case SYSTEM = 'system' ;
case SEARCH = 'search' ;
}
Permission Examples
perspectivePermission : 'experienceEcommerce.personalizationTargetingRules'
perspectivePermission : 'experienceEcommerce.personalizationTargetGroups'
perspectivePermission : 'experienceEcommerce.portalEngine'
perspectivePermission : 'experienceEcommerce.emails'
perspectivePermission : 'dataManagement.portalEngineCollections'
perspectivePermission : 'dataManagement.bookmarkLists'
perspectivePermission : 'dataManagement.tagConfiguration'
perspectivePermission : 'reporting.dashboards'
perspectivePermission : 'quickAccess.open_asset'
perspectivePermission : 'quickAccess.open_document'
perspectivePermission : 'system.users'
perspectivePermission : 'system.roles'
How It Works
Frontend checks perspectivePermission against active perspective
Backend provides list of enabled permissions per perspective
Navigation filters items based on permission check
Perspective Editor uses these permissions to configure perspectives
const isAllowedInPerspective = (permission : string ): boolean => {
const activePerspective = selectActivePerspective (store.getState ())
if (!activePerspective) return false
return isPathTrue (activePerspective.contextPermissions , permission)
}
Backend Permission Registration (PHP)
🚨 IMPORTANT: Where to Register Permissions The approach differs based on which bundle you're working in:
studio-ui-bundle (Core) If you're adding permissions for studio-ui-bundle features, register them directly in studio-backend-bundle :
Primary Location (Most Permissions):
Additional Permissions via Subscribers:
Additional permissions can be registered via event subscribers in studio-backend-bundle
Multiple context-specific subscribers add their permissions via ContextPermissionsServiceInterface
Custom Bundles (e.g., personalization-bundle, your-bundle) If you're creating a custom bundle (first-party or third-party), register permissions in your own bundle using a StudioContextPermissionsSubscriber as shown below.
For studio-ui-bundle: Add to ContextPermissionService Most core studio-ui-bundle permissions are defined directly in the ContextPermissionService:
<?php
namespace Pimcore \Bundle \StudioBackendBundle \Perspective \Service ;
final readonly class ContextPermissionService implements ContextPermissionsServiceInterface
{
private function getDefaultPermissions ( ): array
{
return [
new ContextPermissionData (
'open_asset' ,
ContextPermissionGroups ::QUICK_ACCESS ->value,
true
),
new ContextPermissionData (
'open_document' ,
ContextPermissionGroups ::QUICK_ACCESS ->value,
true
),
new ContextPermissionData (
'yourNewFeature' ,
ContextPermissionGroups ::DATA_MANAGEMENT ->value,
true
),
];
}
}
For Custom Bundles: Create a StudioContextPermissionsSubscriber Permissions for custom bundles must be registered using a StudioContextPermissionsSubscriber in your bundle.
Step 1: Create the Subscriber <?php
namespace YourVendor \YourBundle \EventSubscriber ;
use Pimcore \Bundle \StudioBackendBundle \Perspective \Model \ContextPermissionData ;
use Pimcore \Bundle \StudioBackendBundle \Perspective \Service \ContextPermissionsServiceInterface ;
use Pimcore \Bundle \StudioBackendBundle \Perspective \Util \Constant \ContextPermissionGroups ;
use Symfony \Component \EventDispatcher \EventSubscriberInterface ;
use Symfony \Component \HttpKernel \KernelEvents ;
final readonly class StudioContextPermissionsSubscriber implements EventSubscriberInterface
{
public function __construct (
private ContextPermissionsServiceInterface $permissionsService ,
) {
}
public static function getSubscribedEvents ( ): array
{
return [
KernelEvents ::CONTROLLER => 'addContextPermissions' ,
];
}
public function addContextPermissions ( ): void
{
$this ->permissionsService->add (
new ContextPermissionData (
'yourFeature' , // Permission key
ContextPermissionGroups ::DATA_MANAGEMENT ->value, // Group
true // Default enabled
)
);
}
}
Step 2: Register as Service (Auto-configured) Most Symfony bundles auto-configure event subscribers. If not, add to services.yaml:
services:
YourVendor\YourBundle\EventSubscriber\StudioContextPermissionsSubscriber:
tags:
- { name: kernel.event_subscriber }
ContextPermissionData Parameters new ContextPermissionData (
string $key ,
string $group ,
bool $defaultValue = true
)
Real-World Example: Personalization Bundle <?php
namespace Pimcore \Bundle \PersonalizationBundle \EventSubscriber ;
use Pimcore \Bundle \StudioBackendBundle \Perspective \Model \ContextPermissionData ;
use Pimcore \Bundle \StudioBackendBundle \Perspective \Service \ContextPermissionsServiceInterface ;
use Pimcore \Bundle \StudioBackendBundle \Perspective \Util \Constant \ContextPermissionGroups ;
use Symfony \Component \EventDispatcher \EventSubscriberInterface ;
use Symfony \Component \HttpKernel \KernelEvents ;
final readonly class StudioContextPermissionsSubscriber implements EventSubscriberInterface
{
public function __construct (
private ContextPermissionsServiceInterface $permissionsService ,
) {
}
public static function getSubscribedEvents ( ): array
{
return [
KernelEvents ::CONTROLLER => 'addContextPermissions' ,
];
}
public function addContextPermissions ( ): void
{
$this ->permissionsService->add (
new ContextPermissionData (
'personalizationTargetingRules' ,
ContextPermissionGroups ::EXPERIENCE_ECOMMERCE ->value
)
);
$this ->permissionsService->add (
new ContextPermissionData (
'personalizationTargetGroups' ,
ContextPermissionGroups ::EXPERIENCE_ECOMMERCE ->value
)
);
}
}
Translation Keys You need two sets of translation keys:
1. Navigation Item Label Used in the main navigation menu.
your-feature:
navigation:
title: Your Feature Name
2. Perspective Editor Label Used in the Perspective Editor for enabling/disabling the feature.
perspective-editor:
form:
main-nav-permission:
dataManagement:
yourFeature: Data Management > Your Feature Name
Real-World Example: Target Groups
personalization:
target-groups: Target Groups
perspective-editor:
form:
main-nav-permission:
experienceEcommerce:
personalizationTargetGroups: Personalisation / Targeting > Target Groups
Group Category Labels If adding a new group category label:
perspective-editor:
form:
main-nav-permission:
category:
experienceEcommerce: Experience & E-commerce
dataManagement: Data Management
reporting: Reporting
Complete Flow Diagram ┌─────────────────────────────────────────────────────────────┐
│ 1. FRONTEND: Register Navigation Item │
│ │
│ mainNavRegistry.registerMainNavItem({ │
│ path: 'Group/SubGroup/Item', │
│ perspectivePermission: 'group.permissionKey' │
│ }) │
└────────────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 2. BACKEND: Register Permission (PHP) │
│ │
│ StudioContextPermissionsSubscriber::addContextPermissions()│
│ → permissionsService->add( │
│ new ContextPermissionData('permissionKey', 'group') │
│ ) │
└────────────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 3. TRANSLATIONS: Add Translation Keys │
│ │
│ - your-feature.navigation.title │
│ - perspective-editor.form.main-nav-permission.group.key │
└────────────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 4. PERSPECTIVE CONFIGURATION │
│ │
│ User enables/disables in Perspective Editor │
│ Settings stored per perspective │
└────────────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 5. RUNTIME: Navigation Filtering │
│ │
│ - Frontend checks perspectivePermission │
│ - Only shows nav items with enabled permissions │
└─────────────────────────────────────────────────────────────┘
Testing Your Navigation Item
1. Verify Registration Check browser console for your module initialization:
console .log ('YourFeatureModule initialized' )
2. Check Perspective Editor
Navigate to System > Perspective Editor
Select or create a perspective
Expand the appropriate group (e.g., "Experience & E-commerce")
Find your permission checkbox
Verify translation label is correct
3. Toggle Perspective Permission
Enable your permission in the perspective
Save perspective
Reload Studio
Verify navigation item appears
Disable permission and verify item disappears
4. Check Translation
Change language in user settings
Verify navigation label updates correctly
Check perspective editor label in different language
Common Patterns
Pattern 1: Simple Feature Navigation
mainNavRegistry.registerMainNavItem ({
path : 'DataManagement/Your Feature' ,
label : 'your-feature.title' ,
perspectivePermission : 'dataManagement.yourFeature' ,
widgetConfig : {
name : 'Your Feature' ,
id : 'your-feature' ,
component : 'your-feature' ,
config : {
translationKey : 'your-feature.title' ,
icon : { type : 'name' , value : 'your-icon' }
}
}
})
Pattern 2: Multiple Related Items
mainNavRegistry.registerMainNavItem ({
path : 'ExperienceEcommerce/YourBundle/Feature 1' ,
label : 'your-bundle.feature1' ,
order : 10 ,
perspectivePermission : 'experienceEcommerce.feature1' ,
widgetConfig : { }
})
mainNavRegistry.registerMainNavItem ({
path : 'ExperienceEcommerce/YourBundle/Feature 2' ,
label : 'your-bundle.feature2' ,
order : 20 ,
perspectivePermission : 'experienceEcommerce.feature2' ,
widgetConfig : { }
})
Pattern 3: With User Permission Check
mainNavRegistry.registerMainNavItem ({
path : 'System/Your Admin Feature' ,
label : 'your-feature.admin' ,
permission : 'admin' ,
perspectivePermission : 'system.yourAdminFeature' ,
widgetConfig : { }
})
Common Mistakes
❌ Missing Backend Registration
mainNavRegistry.registerMainNavItem ({
perspectivePermission : 'dataManagement.yourFeature'
})
❌ Wrong Group Name
new ContextPermissionData (
'yourFeature' ,
'dataManagment'
)
new ContextPermissionData (
'yourFeature' ,
ContextPermissionGroups ::DATA_MANAGEMENT ->value
)
❌ Mismatched Permission Keys
perspectivePermission : 'dataManagement.yourFeature'
new ContextPermissionData ('your-feature' , ...)
❌ Missing Translation Keys
your-feature:
navigation:
title: Your Feature
your-feature:
navigation:
title: Your Feature
perspective-editor:
form:
main-nav-permission:
dataManagement:
yourFeature: Data Management > Your Feature
Quick Reference Checklist To add a navigation item with perspective permissions:
Frontend (TypeScript):
Backend (PHP):
Translations:
Testing:
Next Steps