Plugin Nav Registry
Contract for accumulating plugin top-level nav groups and config-driven page definitions, resolved per package for header rendering and plugin page serving.
Overview
App\Sdk\Nav\PluginNavRegistry is the in-memory registry of plugin navigation groups and page definitions. Registrations accumulate at plugin boot via the registrar's navGroup() / page() seams (manifest-gated: every group, item, and page must be declared in signals.yaml nav: / pages:).
The app header renders each registered group as a top-level mega dropdown; App\Livewire\Plugins\PluginPage serves the declared pages at /plugins/{vendor}/{name}/{page} inside a group sidebar that mirrors the group's items. Disabled plugins never boot, so their groups and pages disappear on the next process cycle.
Public surface
| Method | Purpose |
|---|---|
registerGroup() |
Append one PluginNavGroup for a package (one group per plugin) |
registerPage() |
Append one PluginPageDefinition keyed by package + page key |
groups() |
Return every registered group in append order |
groupFor() |
Return the group registered by a package, or null |
pageFor() |
Return a package's page definition by key, or null |
flush() |
Clear all groups and pages (Octane-safe boot lifecycle) |
Accepted definition shape
Groups are immutable App\Sdk\Nav\PluginNavGroup values (label, icon, ordered App\Sdk\Nav\PluginNavItem items with key/label/page/permission/icon); pages are App\Sdk\Nav\PluginPageDefinition values (key, title, description, console layout, ordered stat-grid / table / html sections, and the data-provider callable registered through page()).
Item permissions are enforced at render (PluginNavGroup::visibleItems()) and per request in PluginPage; section data providers are failure-isolated — a throwing provider logs and renders empty sections.
Worked example
use App\Sdk\Nav\PluginNavGroup;
use App\Sdk\Nav\PluginNavItem;
use App\Sdk\Nav\PluginNavRegistry;
$registry = app(PluginNavRegistry::class);
$registry->registerGroup(new PluginNavGroup(
package: 'signals/slots-demo',
label: 'Slots Demo',
icon: 'puzzle-piece',
items: [new PluginNavItem(key: 'overview', label: 'Overview', page: 'overview', permission: 'signals.slotsdemo.view', icon: 'chart-bar')],
));
// Header rendering + PluginPage resolution:
$group = $registry->groupFor('signals/slots-demo');
$page = $registry->pageFor('signals/slots-demo', 'overview');