This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.
Creating collapsible sidenav menu
On this tutorial, I will try to explain how to make a similar System sidebar collapsible menu.
Register navigation with extra options
In the registerNavigation()
function of your plugin, add some extra options on sideMenu
items.
This is an example of one plugin I'm developing.
public function registerNavigation(){
return [
'realestate' => [
'label' => \Lang::get('pronet.realestate::lang.app.name'),
'url' => Backend::url('pronet/realestate/dashboard'),
'icon' => 'icon-building',
'permissions' => ['pronet.realestate.*'],
'order' => 500,
'sideMenu' => [
'owners' => [
'label' => \Lang::choice('pronet.realestate::lang.owners.title', 2),
'icon' => 'fa fa-users',
'url' => Backend::url('pronet/realestate/owners'),
'permissions' => ['pronet.realestate.access_owners'],
'group' => 'owners',
'description' => \Lang::get('pronet.realestate::lang.owners.description'),
],
'zones' => [
'label' => \Lang::choice('pronet.realestate::lang.zones.title', 2),
'icon' => 'fa fa-map-marker',
'url' => Backend::url('pronet/realestate/zones'),
'permissions' => ['pronet.realestate.access_zones'],
'group' => 'address',
'description' => \Lang::get('pronet.realestate::lang.zones.description'),
],
'types' => [
'label' => \Lang::choice('pronet.realestate::lang.types.title', 2),
'icon' => 'fa fa-building-o',
'url' => Backend::url('pronet/realestate/types'),
'permissions' => ['pronet.realestate.access_types'],
'group' => 'properties',
'description' => \Lang::get('pronet.realestate::lang.types.description'),
],
'attributecategories' => [
'label' => \Lang::choice('pronet.realestate::lang.attributecategories.title', 2),
'icon' => 'fa fa-folder-open',
'url' => Backend::url('pronet/realestate/attributecategories'),
'permissions' => ['pronet.realestate.access_attributecategories'],
'group' => 'attributes',
'description' => \Lang::get('pronet.realestate::lang.attributecategories.description'),
],
'attributes' => [
'label' => \Lang::choice('pronet.realestate::lang.attributes.title', 2),
'icon' => 'fa fa-puzzle-piece',
'url' => Backend::url('pronet/realestate/attributes'),
'permissions' => ['pronet.realestate.access_attributes'],
'group' => 'attributes',
'description' => \Lang::get('pronet.realestate::lang.attributes.description'),
],
'pricetypes' => [
'label' => \Lang::choice('pronet.realestate::lang.pricetypes.title', 2),
'icon' => 'fa fa-font',
'url' => Backend::url('pronet/realestate/pricetypes'),
'permissions' => ['pronet.realestate.access_pricetypes'],
'group' => 'prices',
'description' => \Lang::get('pronet.realestate::lang.pricetypes.description'),
],
'currencies' => [
'label' => \Lang::choice('pronet.realestate::lang.currencies.title', 2),
'icon' => 'fa fa-money',
'url' => Backend::url('pronet/realestate/currencies'),
'permissions' => ['pronet.realestate.access_currencies'],
'group' => 'prices',
'description' => \Lang::get('pronet.realestate::lang.currencies.description'),
],
'transactions' => [
'label' => \Lang::choice('pronet.realestate::lang.transactions.title', 2),
'icon' => 'fa fa-exchange',
'url' => Backend::url('pronet/realestate/transactions'),
'permissions' => ['pronet.realestate.access_transactions'],
'group' => 'prices',
'description' => \Lang::get('pronet.realestate::lang.transactions.description'),
],
]
]
];
}
The extra parameters are group, description, keywords. Description and keywords are used like in System menu.
// http://octobercms.com/docs/plugin/registration#backend-settings
The optional keywords parameter is used by the settings search feature. If keywords are not provided, the search uses only the settings item label and description.
The group parameter work like the category parameter in backend settings.
Create partial files
In the root of your plugin, create a directory named partials with this files:
/plugins/pronet/realestate/partials/
- _sidebar.htm // <-- New sidebar wrapper
- _sidebar_menu_toolbar.htm // <-- Search form on top of sidebar
- _sidebar_menu.htm // <-- Sidebar menu
Sidebar Wrapper (_sidebar.htm)
Remember to edit the plugin address to your plugin.
<div 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('@/plugins/pronet/realestate/partials/_sidebar_menu_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('@/plugins/pronet/realestate/partials/_sidebar_menu.htm') ?>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Sidebar Search Form (_sidebar_menu_toolbar.htm)
<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>
Sidebar Menu (_sidebar_menu.htm)
<?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('pronet.realestate::lang.global.sidenav.' . $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="<?= $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; ?>
Register Sidenav Partial in Plugin.php
public function register()
{
BackendMenu::registerContextSidenavPartial('Pronet.RealEstate', 'realestate', '@/plugins/pronet/realestate/partials/_sidebar.htm');
}
Final Result
If I don't forget nothing ;) and you write all, can see something like this:
My Plugin Menu
Sorry my english. I hope this help someone...
I have problem with registerContextSidenavPartial
this partial is in partials folder The partial '@/plugins/minerd/dgetp/partials/__sidebar.htm.htm' is not found.
jprevot said:
I have problem with registerContextSidenavPartial
this partial is in partials folder The partial '@/plugins/minerd/dgetp/partials/__sidebar.htm.htm' is not found.
You have two typo:
- __sidebar with two underscores
- __sidebar.htm.htm
htm
twice
It works perfect!
Only thing is that you need to add
use BackendMenu;
in the Plugin.php
file
and the name of the files and how they are been called in the partials are not the same, so updating:
public function register() { BackendMenu::registerContextSidenavPartial('Pronet.RealEstate', 'realestate', '@/plugins/pronet/realestate/partials/_sidebar.htm'); }
to
public function register() { BackendMenu::registerContextSidenavPartial('Pronet.RealEstate', 'realestate', '@/plugins/pronet/realestate/partials/_sidenav.htm'); }
and in the _sidenav.html
:
$this->makePartial('@/plugins/pronet/realestate/partials/_sidebar_menu_toolbar.htm')
to
$this->makePartial('@/plugins/pronet/realestate/partials/_sidenav_menu_toolbar.htm')
and
$this->makePartial('@/plugins/alto/contacts/partials/_sidebar_menu.htm')
to
$this->makePartial('@/plugins/alto/contacts/partials/_sidenav_menu.htm')
I have done all the things but after that when I reload the page the sidebar menu disappears. I do not understand what I have done wrong. I have used builder plugin for creating plugins.Please help.
Last updated
tdeveloper0518483 said:
I have done all the things but after that when I reload the page the sidebar menu disappears. I do not understand what I have done wrong. I have used builder plugin for creating plugins.Please help.
That's because the original post data is kind of outdated now since October CMS Stable released. Things have been changed a little bit (especially markup & css).
Last updated
So no usage in combination with the builder plugin? Should be part of the builder backend menu functions, isn`t it?
1-15 of 15