Navbar rendering in module panel¶
Technical documentation for building and rendering the navbar in the admin panel.
Purpose¶
The navbar is built declaratively from a NavbarItem tree, not from hardcoded HTML menus.
Tree sources:
- Core nodes from
CoreNavbarProvider::register(). - Module nodes from
ModuleInterface::registerNavbar().
Lifecycle¶
ModuleLoader::bootAll()callsCoreNavbarProvider::register().- Then
registerNavbar()is called for each loaded module. - In
Public/Views/admin/header.php, the tree is rendered fromNavbarRegistry.
Rendering in header¶
Rendering is done by helper functions:
_xc_nav_visible()- visibility filtering for a node._xc_nav_label()- text label resolution._xc_nav_children()- recursive rendering of child items.
Top-level nodes come from NavbarRegistry::getTopLevel(), child nodes come from NavbarRegistry::getChildren($key).
Visibility rules¶
Checks are performed in _xc_nav_visible():
desktopOnly: hides node on mobile.settingDisabled: hides node when a setting flag is enabled.permissions: OR-check viaAuthorization::check('adv', $permission).- A group with
url='#'is shown only if at least one child is visible. divideris always passed through and rendered as separator.
Rendering specifics¶
dividerrenders as separator without a link.submenuClass('megamenu')enables two-column rendering for long lists.noMobileSubmenudisables child submenu expansion on mobile.
How a module adds a menu item¶
A module adds items only through registerNavbar():
public function registerNavbar(NavbarRegistry $registry): void {
NavbarRegistry::add((new NavbarItem('management.service_setup.my_module'))
->parent('management.service_setup')
->url('my_module')
->label('my_module')
->permissions(['my_module'])
->order(60));
NavbarRegistry::add((new NavbarItem('management.logs.my_module_log'))
->parent('management.logs')
->url('my_module_logs')
->label('', 'My Module Logs')
->permissions(['my_module'])
->order(170));
}
NavbarItem builder API¶
NavbarItem is a fluent value object (src/Core/Module/NavbarItem.php) — chain setters off new NavbarItem($key):
| Method | Purpose |
|---|---|
new NavbarItem($key) |
create a node; $key is its unique section.group.item id |
->parent($parentKey) |
attach under an existing node (omit for a top-level node) |
->url($url) |
target path; '#' makes it a non-navigating group header |
->label($key, $fallback = '') |
translation key, or ('', 'Literal') for fixed text |
->icon($icon) |
icon CSS class for the item |
->permissions([...]) |
OR-list of permission keys; node hidden unless the viewer has one |
->order($n) |
sort position within the parent |
->desktopOnly() |
hide on mobile |
->noMobileSubmenu() |
don't expand this node's submenu on mobile |
->submenuClass('megamenu') |
two-column rendering for long child lists |
->settingDisabled($settingKey) |
hide the node when that panel setting flag is truthy |
->makeDivider() |
render this node as a separator (no link) |
Group node and divider¶
public function registerNavbar(NavbarRegistry $registry): void {
// A group header (url('#')) — shown only if at least one child is visible
NavbarRegistry::add((new NavbarItem('management.my_group'))
->parent('management')
->url('#')
->label('my_group')
->order(50));
// A divider inside that group
NavbarRegistry::add((new NavbarItem('management.my_group.sep1'))
->parent('management.my_group')
->makeDivider()
->order(55));
}
settingDisabled('some_setting')hides the node whenever that setting is truthy (gate a feature behind a toggle). Visibility is also viewer-scoped: thepermissionsOR-check runs against the current user viaAuthorization::check('adv', …), so an admin and a reseller can see different subsets of the same tree.
Practical rules for modules¶
- Use unique
keyvalues insection.group.itemformat. - Set
parentto an existing core tree node or your own already-added node. - Position items using
orderinside one parent. - Use
label('translation_key')for translatable text. - Use
label('', 'Literal Text')for fixed literal text. - If the module has no menu items, keep
registerNavbar()empty.
Related files¶
| File | Role |
|---|---|
src/Core/Module/NavbarRegistry.php |
Collects navbar items from providers |
src/Core/Module/NavbarItem.php |
Navbar item value object |
src/Core/Module/CoreNavbarProvider.php |
Built-in core menu items |
src/Public/Views/admin/header.php |
Renders the navbar tree |