Register custom side navigation for your plugin
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.
'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