oskar.villani40843
oskar.villani40843

Hello,

for the sake of UI simplicity I would like to integrate the rainlab user menu (the submenu items in fact) into a self developed plugin submenu. Found some hints here, but could not make it run completely: I am able to show the rainlab.user and rainlab.usergroup submenu in my submenu, but as soon as these menu items are clicked, my submenu disappears.

Any hints, tipps, tricks? Thanks in advance!

mjauvin
mjauvin

That's because you also need to set the navigation context, see below:

https://octobercms.com/docs/backend/controllers-ajax#navigation-context

oskar.villani40843
oskar.villani40843

Hi, thanks for your reply mjauvin!

Unfortunately I am still stuck with where to set the context. My plugin.php contains this:

public function boot()
{   
    Event::listen('backend.menu.extendItems', function($manager) {
        $manager->removeMainMenuItem('Rainlab.User', 'user');

        $manager->addSideMenuItems('Pdsci.Library', 'library', [
            'user' => [
                'label' => 'User',
                'icon'  => 'icon-upload',
                'code'  => 'user',
                'owner' => 'RainLab.User',
                'url'   => Backend::url('rainlab/user/users')
            ]
        ]);
    });   
}

So I guess I have to add something to my(?) controller like

BackendMenu::setContext( ... );

But I could not figure out yet where to use and what params to use.

My plugin controller already has

 BackendMenu::setContext('Pdsci.Library', 'library');

but with all changes I destroy either my own plugin submenu or something else so far. May be I am missing a concept thing?

Thanks in advance!

mjauvin
mjauvin
mjauvin

In summary, just add this to your boot() method:

   \RainLab\User\Controllers\Users::extend(function ($controller) {
      $controller->bindEvent('page.beforeDisplay', function ($action, $params) {     
         BackendMenu::setContext('Pdsci.Library', 'library', 'user');
      });
   });
oskar.villani40843
oskar.villani40843

Hello mjauvin,

thank you very much for your solutions! This was a great help and finally there are now two solutions :) The last you suggested and the first by the link to the LukeTowers Blog. Just as a help for all, here is the complete code for solution one too:

The affected file is the Plugin.php in the example case in /pdsci/library/

<?php namespace Pdsci\Library;

use Event;                               // has to be added to the default
use Backend;                             // dto.
use BackendMenu;                         // dto
use System\Classes\PluginBase;
use Rainlab\User\Models\User as UserModel;  // adding the 'highjacked' model 

class Plugin extends PluginBase
{
    public function registerComponents()
    {
    }

    public function registerSettings()
    {
    }

    public function boot()
    {   
        Event::listen('backend.menu.extendItems', function($manager) {
            // first the rainlab user main menu is removed
            $manager->removeMainMenuItem('Rainlab.User', 'user');

            // then a new 'user' submenu is added to the own plugin
            // referring to the rainlab one
            // note: the second param 'library' here as well as 'user' above 
            // is the main menu code :)
            $manager->addSideMenuItems('Pdsci.Library', 'library', [
                'user' => [
                'label' => 'User',
                'icon'  => 'icon-upload',
                'code'  => 'user',
                'owner' => 'RainLab.User',
                'url'   => Backend::url('rainlab/user/users')
            ]
        ]);
    });   

    // The next few lines have to be added to still display the library submenu
    // when the user submenu is clicked - otherwise the submenu disappears
    // as long as the main library menu is clicked again.
    // Hook into the backend.page.beforeDisplay since that event will be run 
    // right before the view is rendered which makes it perfect for our use case
    Event::listen('backend.page.beforeDisplay', function ($controller, $action, $params) {
        // We only want our changes to affect our highjacked controller. 
        // Note: this has to be the rainlab user controller, NOT the library controller!
        if (!($controller instanceof \Rainlab\User\Controllers\Users)) {
            return;
        }
        // We now override the existing navigation context by setting it once 
        // again and pointing to our navigation item that we created earlier
        BackendMenu::setContext('Pdsci.Library', 'library');
    });
)

1-6 of 6