` tag itself:
```php
{!! $MenuName->asDiv( ['class' => 'awesome-div'] ) !!}
```
Result:
```html
```
#### Menu as Bootstrap 3 Navbar
Laravel Menu provides a parital view out of the box which generates menu items in a bootstrap friendly style which you can **include** in your Bootstrap based navigation bars:
You can access the partial view by `config('laravel-menu.views.bootstrap-items')`.
All you need to do is to include the partial view and pass the root level items to it:
```html
...
@include(config('laravel-menu.views.bootstrap-items'), ['items' => $mainNav->roots()])
...
```
This is how your Bootstrap code is going to look like:
```html
```
In case you are using bootstrap 5 (currently in beta) you need to set the `data-toggle-attribute` option from `data-toggle` to `data-bs-toggle` in your `config/laravel-menu/settings.php`.
#### Adding class attributes to child items
Like adding a class to the menu `ul` and `ol`, classes can be added the submenu too. The three parameters to `asUl` are arrays as follows:
- The first array is the attributes for the list: for example, `ul`
- The second is the attributes for the child lists, for example, `ul>li>ul`
- The third array is attributes that are added to the attributes of the `li` element
With this you can add a class to the child menu (submenu) like this:
```php
{!! $menu->asUl( ['class' => 'first-level-ul'], ['class' => 'second-level-ul'] ) !!}
```
## Subset Menus
With your menu constructed you can call any of our subset menu functions to get a new `Builder` to quick generate additional menus.
#### Top Menu
This generates a `Builder` of the top level items, items without a parent.
```php
{!! Menu::get('primary')->topMenu()->asUl() !!}
```
#### Sub Menu
This generates a `Builder` of the immediate children of the active item.
```php
{!! Menu::get('primary')->subMenu()->asUl() !!}
```
#### Sibling Menu
This generates a `Builder` of the siblings of the active item.
```php
{!! Menu::get('primary')->siblingMenu()->asUl() !!}
```
#### Crumb Menu
This generates a `Builder` by recursively getting all of the parent items for the active item (including the active item).
```php
{!! Menu::get('primary')->crumbMenu()->asUl() !!}
```
## Advanced Usage
As noted earlier you can create your own rendering formats.
#### A Basic Example
If you'd like to render your menu(s) according to your own design, you should create two views.
* `View-1` This view contains all the HTML codes like `nav` or `ul` or `div` tags wrapping your menu items.
* `View-2` This view is actually a partial view responsible for rendering menu items (it is going to be included in `View-1`.)
The reason we use two view files here is that `View-2` calls itself recursively to render the items to the deepest level required in multi-level menus.
Let's make this easier with an example:
```php
Menu::make('MyNavBar', function($menu){
$menu->add('Home');
$menu->add('About', ['route' => 'page.about']);
$menu->about->add('Who are we?', 'who-we-are');
$menu->about->add('What we do?', 'what-we-do');
$menu->add('Services', 'services');
$menu->add('Contact', 'contact');
});
```
In this example we name View-1 `custom-menu.blade.php` and View-2 `custom-menu-items.blade.php`.
**custom-menu.blade.php**
```php
```
**custom-menu-items.blade.php**
```php
@foreach($items as $item)
hasChildren()) class="dropdown" @endif>
{!! $item->title !!}
@if($item->hasChildren())
@endif
@endforeach
```
Let's describe what we did above, In `custom-menus.blade.php` we put whatever HTML boilerplate code we had according to our design, then we included `custom-menu-items.blade.php` and passed the menu items at *root level* to `custom-menu-items.blade.php`:
```php
...
@include('custom-menu-items', ['items' => $menu->roots()])
...
```
In `custom-menu-items.blade.php` we ran a `foreach` loop and called the file recursively in case the current item had any children.
To put the rendered menu in your application template, you can simply include `custom-menu` view in your master layout.
#### Control Structure For Blade
Laravel menu extends Blade to handle special layouts.
##### @lm_attrs
You might encounter situations when some of your HTML properties are explicitly written inside your view instead of dynamically being defined when adding the item; However you will need to merge these static attributes with your Item's attributes.
```php
@foreach($items as $item)
hasChildren()) class="dropdown" @endif data-test="test">
{!! $item->title !!}
@if($item->hasChildren())
@endif
@endforeach
```
In the above snippet the `li` tag has class `dropdown` and `data-test` property explicitly defined in the view; Laravel Menu provides a control structure which takes care of this.
Suppose the item has also several attributes dynamically defined when being added:
```php
$menu->add('Dropdown', ['class' => 'item item-1', 'id' => 'my-item']);
```
The view:
```php
@foreach($items as $item)
hasChildren()) class="dropdown" @endif data-test="test" @lm_endattrs>
{!! $item->title !!}
@if($item->hasChildren())
@endif
@endforeach
```
This control structure automatically merges the static HTML properties with the dynamically defined properties.
Here's the result:
```
...
...
...
```
#### Attributes and Callback function of item
When printing a list, you can:
Set the attributes for the list element;
Set the callback function, to add a prefix to each link or by condition ("?id={$id}") and much more.
* **Example of converting a menu into a drop-down list for mobile**
Controller:
```php
$items=[
'copy'=>[
'icon'=>'fa-copy',
'title'=>'Copy',
'text'=>'Copy',
'link_attribute'=>[
'class'=>'nav-link',
'href'=> url(Request::capture()->path()."/copy"),
]
],
];
$controlItem = Menu::make('controlItem', function($menu) use ($items){
foreach ($items as $key => $item) if(!isset($item['visible']) || $item['visible']){
$menu->add($item['text'],['title'=>$item['title']])
->append('')
->prepend('
')
->link->attr($item['link_attribute']);
}
});
return view('layouts.table.view',[
'controlItem' => $controlItem
]);
```
View: layouts.table.view
```php
-
asUl(['class'=>'dropdown-menu', 'role'=>'menu'],[],['class'=>'dropdown-item']); ?>
asUl(['class'=>'control-items'],[],['class'=>'nav-item']); ?>
```
* **Example of printing the recording management menu**
Controller:
```php
$items=[
'copy'=>[
'icon'=>'fa-copy',
'title'=>'Copy',
'text'=>'Copy',
'link_attribute'=>[
'class'=>'nav-link',
'href'=> url(Request::capture()->path()."/copy"),
]
],
];
$controlItem = Menu::make('controlItem', function($menu) use ($items){
foreach ($items as $key => $item) if(!isset($item['visible']) || $item['visible']){
$menu->add($item['text'],['title'=>$item['title']])
->append('')
->prepend('
')
->link->attr($item['link_attribute']);
}
});
return view('layouts.table.view',[
'controlItem' => $controlItem
]);
```
View: layouts.table.view (use in a cycle with different IDs)
```php
echo (isset($controlItem)) ? $controlItem->asUl(
['class'=>'dropdown-menu control-item'],
[],
['class'=>'nav-item'],
function($item, &$children_attributes, &$item_attributes, &$link_attr, &$id){
$link_attr['href'] .= "/".(int)$id;
},
$id):'';
```
## Configuration
You can adjust the behavior of the menu builder in `config/settings.php` file. Currently it provide a few options out of the box:
* **auto_activate** Automatically activates menu items based on the current URI
* **activate_parents** Activates the parents of an active item
* **active_class** Default CSS class name for active items
* **restful** Activates RESTful URLS. E.g `resource/slug` will activate item with `resource` url.
* **cascade_data** If you need descendants of an item to inherit meta data from their parents, make sure this option is enabled.
* **rest_base** The base URL that all restful resources might be prefixed with.
* **active_element** You can choose the HTML element to which you want to add activation classes (anchor or the wrapping element).
You're also able to override the default settings for each menu. To override settings for menu, just add the lower-cased menu name as a key in the settings array and add the options you need to override:
```php
return [
'default' => [
'auto_activate' => true,
'activate_parents' => true,
'active_class' => 'active',
'active_element' => 'item', // item|link
'restful' => true,
],
'yourmenuname' => [
'auto_activate' => false
],
];
```
**Alternatively**, you can override the default settings with the following methods. Or you can add new custom settings to the menu.
```php
return [
'default' => [
'auto_activate' => true,
'activate_parents' => true,
'active_class' => 'active',
'active_element' => 'item', // item|link
'restful' => true,
],
'mysidebar' => [
'active_class' => 'active-class-mysidebar',
],
'mynavbar' => [
'active_class' => 'active-class-mynavbar',
],
];
```
**Example 1:**
Override default settings
```php
Menu::make('MySidebar', function ($menu) {
$menu->options([
'active_class' => 'new-active-class',
]);
$menu->add('Home');
$menu->add('About', 'about');
});
/**
* Results:
[
'auto_activate' => true,
'activate_parents' => true,
'active_class' => 'new-active-class'
'active_element' => 'item',
'restful' => true,
]
*/
```
**Example 2:**
Add new settings specific to the menu.
```php
Menu::make('MySidebar', function ($menu) {
$menu->options([
'inactive_class' => 'custom-inactive-class-mysidebar',
]);
$menu->add('Home');
$menu->add('About', 'about');
});
/**
* Results:
[
'auto_activate' => true,
'activate_parents' => true,
'active_class' => 'active-class-mysidebar'
'active_element' => 'item',
'restful' => true,
'inactive_class' => 'custom-inactive-class-mysidebar',
]
*/
```
**Example 3:**
Add custom settings and get the rest of the settings from `MySidebar`.
```php
Menu::make('MyNavbar', function ($menu) {
$menu->options([
'inactive_class' => 'custom-inactive-class-mynavbar',
], 'MySidebar'); // or mysidebar
$menu->add('Home');
$menu->add('About', 'about');
});
/**
* Results:
[
'auto_activate' => true,
'activate_parents' => true,
'active_class' => 'active-class-mysidebar'
'active_element' => 'item',
'restful' => true,
'inactive_class' => 'custom-inactive-class-mynavbar',
]
*/
```
**Example 4:**
Override all settings (including default settings) and add new ones.
```php
Menu::make('MyNavbar', function ($menu) {
$menu->options([
'active_class' => 'active',
], null);
$menu->add('Home');
$menu->add('About', 'about');
});
/**
* Results:
[
'active_class' => 'active'
]
*/
```
**Example 5:**
Or you can use it like this
```php
Menu::make('MyNavbar', function ($menu) {
$menu->add('Home');
$menu->add('About', 'about');
}, [
'inactive_class' => 'custom-inactive-class-mynavbar',
]);
/**
* Results:
[
'auto_activate' => true,
'activate_parents' => true,
'active_class' => 'active-class-mynavbar'
'active_element' => 'item',
'restful' => true,
'inactive_class' => 'custom-inactive-class-mynavbar',
]
*/
```
## If You Need Help
Please submit all issues and questions using GitHub issues and I will try to help you.
## Contributing
Please feel free to submit pull requests if you can improve or add any features.
We are currently using PSR-2+Symfony formatting. This is easy to implement and check with the [PHP Coding Standards Fixer](http://cs.sensiolabs.org/).
Once you have installed php-cs-fixer and added it to your path, simply run the following command in the laravel-menu folder prior to committing.
```bash
$ php-cs-fixer fix . --rules=@Symfony
```
While everyone has different opinions on formatting, this tool will help provide convenient consistency.
## Credits
* [Dustin Graham](https://github.com/dustingraham)
* [Reza Lavarian](https://github.com/lavary)
* [All Contributors](https://github.com/lavary/laravel-menu/graphs/contributors)
## License
*Laravel-Menu* is free software distributed under the terms of the MIT license.