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