Allowing plugins using modules to add multiple items to the CP sidebar nav #18432
Replies: 2 comments
-
|
use craft\base\Event;
use craft\events\RegisterCpNavItemsEvent;
use craft\web\twig\variables\Cp;
use Illuminate\Support\Collection;
Event::on(Cp::class, Cp::EVENT_REGISTER_CP_NAV_ITEMS, function(RegisterCpNavItemsEvent $event) {
$index = Collection::make($event->navItems)->search(fn(array $item) => $item['url'] === 'my-plugin-handle');
if ($index !== false) {
array_splice($event->navItems, $index, 0, [
[
'url' => 'foo-bar',
'label' => 'My Extra Section',
'icon' => 'ufo',
],
]);
}
}); |
Beta Was this translation helpful? Give feedback.
-
|
@brandonkelly I've refactored things to maybe improve them for most use cases but fwiw, I think this solution doesn't fully solve the problem and until plugins can provide multiple nav items or modules can register nav items on an equal standing as plugins, there is always going to be room for bugs to show up. While I think the above is a good event for a developer to use in a custom module on a project, as they have project context, if first party plugins have to rely on making assumptions about modifying a project-specific nav, one plugin may succeed but if there are ever two there is no clear order of responsibility or way to make assumptions about what another plugin might do. The plugin that gets loaded first might be changing things in a way that the plugin using the event second can't anticipate. The responsibility of the nav output for plugins should be in Craft's hands (and it is, unless they need multiple nav items). The logic is currently there is some Craft stuff at the top and bottom of the nav and the plugins all register their nav items to get inserted into the middle and Craft reorders them to be alphabetical based on the nav labels (but alphabetical ordering of the middle nav items happens in the getAllPlugins() method and plugins are allowed only one nav item, so there is no way to just add another nav item to the list and get it in alphabetical order like the rest of the middle nav items) In my case, I'm grabbing a list of installed plugins and filtering them by the ones that have a CP nav section; I'm adding an unnecessary setting in my own plugins to set the hasCpSection setting to true just so I know there will be at least one plugin in the middle of the nav I can identify and get an index from; and then I'm removing all my default plugin nav items and reordering the list of the rest of the plugins with nav items with a merged list of my module nav items. It works, sometimes at least, but is enough code to feel like I'm taking responsibility that I shouldn't in my code and it feels like enough weird code that nobody will be assuming is there to raise the chance something will go wrong again at some point. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Craft 5.9 changed a key in the default nav items and revealed a hacky solution I had been using to workaround.
Currently:
craft\web\twig\variables\Cp::nav()method assumes that plugins only have one nav item to add to the sidebar:cms/src/web/twig/variables/Cp.php
Lines 295 to 303 in 7db0685
craft\web\twig\variables\Cp::EVENT_REGISTER_CP_NAV_ITEMSassumes that the watcher can manipulate the nav after it is fully prepared without causing other issues:cms/src/web/twig/variables/Cp.php
Lines 368 to 373 in 7db0685
My situation:
I have multiple plugins that rely on more than one underlying shared Yii modules and it's possible that a single plugin needs to output multiple top level CP nav items with subnavs specific to each of their use cases.
EVENT_REGISTER_CP_NAV_ITEMSbut, if I want my modules to appear alongside the other plugin nav items in alphabetical order as Craft outputs them, I have to make assumptions about what nav items exist to try to place the module navs in the right place. On top of this I imagine what I'm doing might create tricker situations for any other plugin that was focused on letting users rearrange the nav without plugins like mine doing messy things with rearranging the nav also, just to try to fit in. If I don't try to rearrange stuff and figure out how to place my module nav items in the middle of the nav alongside the other plugin nav items, my plugin/module nav items appear at the end of the sidebar nav down below the Settings and Plugin Store nav items, which would feel out of order to users.Ideally:
I don't know what the best solution is but two things that might make this situation easier could be:
I'm raising this as a discussion in case I'm missing something obvious, but would love to turn this into a FR if this sounds reasonable.
Beta Was this translation helpful? Give feedback.
All reactions