How To Use
Menus can be registered anywhere in your application, but there is a special location for this purpose: resources/menus
folder.
Each PHP in this file is auto-loaded and a $menu
variable is injected to them.
$menu
is just an instance of the Atorscho\Menus\Menu
class singleton that allows you to register multiple navigation menus for your application.
Quick Start
After publishing vendor files, you may find new default.php
file in resources/menus
. This is just some sort of a boilerplate to get you started.
<?php
$menu->register('primary', 'Home Page', '/');
$menu->build('primary', function (Builder $builder) {
$builder->add('Services', '/services');
$builder->add('Products', '/products');
$builder->add('Shop', '/shop')
->addChild('Categories', '/categories')
->addChild('Items', '/items');
});
This code creates a nested set of menu items:
- Services
- Products
-> Shop
-> Categories
- Items
To render this in a Blade file:
<ul id="primary">
@foreach(Menu::all('primary') as $item)
<li {{ $item->active() }}>
<a href="{{ $item->url }}">{{ $item->title }}</a>
@if($item->hasChildren())
<ul>
@foreach($item->children() as $child)
<li class="{{ $child->activeClass() }} item">
<a href="{{ $child->url }}">
{{ $child->title }}
</a>
</li>
@endforeach
</ul>
@endif
</li>
@endforeach
</ul>
You may also use
app('menu')
to retrieveMenu
instance:app('menu')->primary as $item
.
Features
Titles and URLs
Menu titles and URLs are automatically escaped.
You may use url()
and route()
helper functions to create links.
Child Items
Each menu item may have an infinite number of nested child elements.
Menu::register('secondary', 'Community', '#', [
[
'title' => 'Forums',
'url' => url('forums'),
'children' => [
[
'title' => 'Our Staff',
'url' => url('forums/staff')
],
[
'title' => 'Sitemap',
'url' => url('forums/sitemap')
]
]
]
]);
Now you may access to its child elements via the property: $item->children
.
Custom Fields
Pretty often you need to add some information to the menu items, such as a counter, number of unread messages or an icon.
To do so, you can use "Custom Fields" that may be applied to every menu item.
Menu::build('admin', function (Builder $builder) {
$builder->add('Categories', '/categories', [], ['count' => 23]);
$builder->add('Users', '/users', [], ['count' => 691]);
});
Let's imagine we have injected a $menu = app('menu')
variable to our Blade view:
<h3>Admin CP</h3>
<ul>
@foreach($menu->admin as $item)
<li>
{{ $item->title }}
<small>({{ $item->count }})</small>
</li>
@endforeach
</ul>
And the result will be:
Admin CP
————————
- Categories (23)
- Users (691)
Active State
Menu items usually have an "active" state, it means when the item is highlighted when the user is currently viewing that page.
For this purpose there is a couple of useful methods that will give the item this state.
Let's take our first example:
<ul id="primary">
@foreach(Menu::all('primary') as $item)
<li {{ $item->active() }}>
<a href="{{ $item->url }}">{{ $item->title }}</a>
</li>
@endforeach
</ul>
An item has three methods:
isActive()
activeAttr()
activeClass()
First one returns either true
or false
depending on current item's state.
The second one outputs an HTML attribute with "active" class name: class="active"
.
The last one simply returns "active" class name. It may be useful when you are adding it to already existing class attribute: <li class="{{ $item->activeClass() }} item">
.
Nested Items
By default an item is always nested (this option may be changed in the configuration file config/menus.php
).
Let's consider this navigation menu:
- Home (/)
- Products (/products)
- Services (/services)
-> Forums (/forums)
-> Members (/forums/members)
- Staff (/forums/staff)
If you open the "Members" page, then it is logical that its parent "Forums" should be active too. For this purpose there is a special custom field nested
.
If you change it to false
, then only the current item will be active.