October CMS resources and help articles

Simple and to the point. Optimized by the community.

Register custom side navigation for your plugin

10
by larryb, last modified on September 12th, 2019

The NavigationManager (available through the BackendMenu facade) has the ability to register a special menu called contextSideNav. This allows you to create custom side menus for your plugins, such as the one used in the System Settings page. This trick will help you re-create the setting style sidenav for your plugin.

Part 1 - Create sidenav partials

Create a new folder in your plugin directory called partials

Create a new file in the partials directory called _sidenav.htm with the contents below:

<!-- Main sidenav menu wrapper -->
<div style="background: steelblue;" class="layout-cell sidenav-tree" 
data-control="sidenav-tree" data-search-input="#settings-search-input">
 <div class="layout">
     <div class="layout-row min-size">
         <?= $this->makePartial('$/author/plugin/partials/_sidenav_search_toolbar.htm') ?>
     </div>
     <div class="layout-row">
         <div class="layout-cell">
             <div class="layout-relative">
                 <div class="layout-absolute">
                     <div class="control-scrollbar" data-control="scrollbar">
                         <?= $this->makePartial('$/author/plugin/partials/_sidenav_menu.htm') ?>
                     </div>
                 </div>
             </div>
         </div>
     </div>
 </div>
</div>

Create a new file in the partials directory called _sidenav_search_toolbar.htm with the contents below:

<!-- Search form on top of sidenav -->
<div class="layout control-toolbar">
    <div class="layout-cell">
        <div class="relative toolbar-item loading-indicator-container size-input-text">
            <input placeholder="<?= e(trans('system::lang.settings.search')) ?>" type="text" name="search" value="" 
                class="form-control icon search"
                id="settings-search-input"
                autocomplete="off"
                data-track-input
                data-load-indicator
                data-load-indicator-opaque
            />
        </div>
    </div>
</div>

Create a new file in the partials directory called _sidenav_menu.htm with the contents below:

<!-- Sidebar menu -->
<?php
$sideMenuItems = BackendMenu::listSideMenuItems();
if ($sideMenuItems):
    $collapsedGroups = explode('|',
isset($_COOKIE['sidenav_treegroupStatus']) ? $_COOKIE['sidenav_treegroupStatus'] : null);
$categories = [];
foreach ($sideMenuItems as $sideItemCode => $item){
    if(!property_exists($item, 'group'))
        $item->group = 'default';
    if(!property_exists($item, 'keywords'))
        $item->keywords = '';
    if(!property_exists($item, 'description'))
        $item->description = '';
    $categories[$item->group][$sideItemCode] = $item;
}
?>        
<ul class="top-level">
<?php foreach ($categories as $category => $items):
        $collapsed = in_array($category, $collapsedGroups);
?>
    <li data-group-code="<?= e($category) ?>"
        <?= $collapsed ? 'data-status="collapsed"' : null ?>
    >
        <div class="group">
            <h3><?= e(trans($category)) ?></h3>
        </div>
        <ul>
        <?php foreach ($items as $item): ?>
            <li class="<?= BackendMenu::isSideMenuItemActive($item) ? 'active' : null ?>"
                data-keywords="<?= e(trans($item->keywords)) ?>">
                <a href="<?= $item->url ?>">
                    <i class="sidebar-menu-item <?= $item->icon ?>"></i>
                    <span class="header"><?= e(trans($item->label)) ?></span>
                    <span class="description"><?= e(trans($item->description)) ?></span>
                </a>
            </li>
        <?php endforeach ?>
        </ul>
    </li>
<?php endforeach ?>
</ul>
<?php endif; ?>

Part 2 - Registering the contextSidenavPartial

Add this code to your Plugin.php file:

use BackendMenu;

public function register()
{
    BackendMenu::registerContextSidenavPartial('Author.PluginName', 'owner', '$/author/plugin/partials/_sidenav.htm');        
}

That's all there is to it. Note we have re-created the settings style menu here, but you would be free to use any style you wish.

Discussion

1 comment

1
arrcrown
Post on July 22nd, 2020 6:15 AM

'sideMenu' => [ 'books_menu' => [ 'label' => 'Label', 'description' => 'Something details', 'iconSvg' => '', 'url' => '', 'permissions' => '', 'group' => 'bookshop', ] ]

after updating to BUILD 467 group, description are not exist. and tried to dump BackendMenu::listSideMenuItems();

can we add another key?

https://octobercms.com/docs/api/backend/classes/navigationmanager#registermenuitems

We use cookies to measure the performance of this website. Do you want to accept these cookies?