PHPackages                             ssntpl/laravel-menu - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. ssntpl/laravel-menu

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

ssntpl/laravel-menu
===================

A quick way to create menus in Laravel 5

v1.7.7(6y ago)019MITPHPPHP &gt;=5.4.0

Since Jul 15Pushed 6y ago1 watchersCompare

[ Source](https://github.com/ssntpl/laravel-menu)[ Packagist](https://packagist.org/packages/ssntpl/laravel-menu)[ Docs](https://github.com/lavary/laravel-menu)[ RSS](/packages/ssntpl-laravel-menu/feed)WikiDiscussions master Synced today

READMEChangelog (2)Dependencies (2)Versions (21)Used By (0)

Laravel Menu
============

[](#laravel-menu)

[![Latest Stable Version](https://camo.githubusercontent.com/ec8c2bbc462b585f0ea071dbb7691bd9334d02c39ae657b5e48589917496d534/68747470733a2f2f706f7365722e707567782e6f72672f6c61766172792f6c61726176656c2d6d656e752f762f737461626c652e737667)](https://packagist.org/packages/lavary/laravel-menu)[![Latest Unstable Version](https://camo.githubusercontent.com/5045c28b7c1927196d5e997cd8cdfda0ed078022cbe34aabeaee76336eca6bca/68747470733a2f2f706f7365722e707567782e6f72672f6c61766172792f6c61726176656c2d6d656e752f762f756e737461626c652e737667)](https://packagist.org/packages/lavary/laravel-menu)[![Total Downloads](https://camo.githubusercontent.com/e415a807b19358542a33b9c34d62ce42249d8b0b734c018c2bfea9128a8a2b82/68747470733a2f2f706f7365722e707567782e6f72672f6c61766172792f6c61726176656c2d6d656e752f646f776e6c6f6164732e737667)](https://packagist.org/packages/lavary/laravel-menu)[![License](https://camo.githubusercontent.com/13a4757f83dc604764d0793275b23a474ce4c53498187161835e588338b10058/68747470733a2f2f706f7365722e707567782e6f72672f6c61766172792f6c61726176656c2d6d656e752f6c6963656e73652e737667)](https://packagist.org/packages/lavary/laravel-menu)

A quick and easy way to create menus in [Laravel 6](http://laravel.com/)

**For Laravel 4.x, check [version 1.5.0](https://github.com/lavary/laravel-menu/tree/v1.5.0)**

Documentation
-------------

[](#documentation)

- [Installation](#installation)
- [Getting Started](#getting-started)
- [Routing](#routing)
    - [URLs](#urls)
    - [Named Routes](#named-routes)
    - [Controller Actions](#controller-actions)
    - [HTTPS](#https)
- [Sub-items](#sub-items)
- [Set Item's ID Manualy](#set-items-id-manually)
- [Set Item's Nicknames Manualy](#set-items-nickname-manually)
- [Referring to Items](#referring-to-items)
    - [Get Item by Title](#get-item-by-title)
    - [Get Item by Id](#get-item-by-id)
    - [Get All Items](#get-all-items)
    - [Get the First Item](#get-the-first-item)
    - [Get the Last Item](#get-the-last-item)
    - [Get the Active Item](#get-the-active-item)
    - [Get Sub-items of the Item](#get-sub-items-of-the-item)
    - [Get the Parent of the Item](#get-the-parent-of-the-item)
    - [Magic Where Methods](#magic-where-methods)
- [Referring to Menu Objects](#referring-to-menu-instances)
- [HTML Attributes](#html-attributes)
- [Manipulating Links](#manipulating-links)
    - [Link's Href Property](#links-href-property)
- [Active Item](#active-item)
    - [RESTful URLs](#restful-urls)
    - [URL Wildcards](#url-wildcards)
    - [Disable activation](#disable-activation)
- [Inserting a Separator](#inserting-a-separator)
- [Append and Prepend](#append-and-prepend)
- [Before and After](#before-and-after)
- [Raw Items](#raw-items)
- [Menu Groups](#menu-groups)
- [URL Prefixing](#url-prefixing)
- [Nested Groups](#nested-groups)
- [Meta Data](#meta-data)
- [Filtering the Items](#filtering-the-items)
- [Sorting the Items](#sorting-the-items)
- [Rendering Methods](#rendering-methods)
    - [Menu as Unordered List](#menu-as-unordered-list)
    - [Menu as Ordered List](#menu-as-ordered-list)
    - [Menu as Div](#menu-as-div)
    - [Menu as Bootstrap 3 Navbar](#menu-as-bootstrap-3-navbar)
    - [Adding class attributes to child items](#adding-class-attributes-to-child-items)
- [Subset Menus](#subset-menus)
    - [Top Menu](#top-menu)
    - [Sub Menu](#sub-menu)
    - [Sibling Menu](#sibling-menu)
    - [Crumb Menu](#crumb-menu)
- [Advanced Usage](#advanced-usage)
    - [A Basic Example](#a-basic-example)
    - [Control Structure for Blade](#control-structure-for-blade)
        - [@lm\_attrs](#lm_attrs)
    - [Attributes and Callback function of item](#attributes-and-callback-function-of-item)
- [Configuration](#configuration)
- [If You Need Help](#if-you-need-help)
- [Contributing](#contributing)
- [License](#license)

Installation
------------

[](#installation)

```
composer require lavary/laravel-menu
```

If you are in Laravel 5.5 you won't need to edit your `config/app.php`, if you are in a previous version of Laravel, please do the following:

Append Laravel Menu service provider to `providers` array in `config/app.php`.

```
'providers' => [

        /*
         * Laravel Framework Service Providers...
         */
        Illuminate\Foundation\Providers\ArtisanServiceProvider::class,
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,

    ...

        Lavary\Menu\ServiceProvider::class,

        ...

],
```

At the end of `config/app.php` add `'Menu'    => Lavary\Menu\Facade::class` to the `$aliases` array:

```
'aliases' => [

    'App'       => Illuminate\Support\Facades\App::class,
    'Artisan'   => Illuminate\Support\Facades\Artisan::class,
    ...
    'Menu'      => Lavary\Menu\Facade::class,

],
```

This registers the package with Laravel and creates an alias called `Menu`.

To use your own settings, publish config.

```
php artisan vendor:publish --provider="Lavary\Menu\ServiceProvider"
```

Getting Started
---------------

[](#getting-started)

You can define the menu definitions inside a [laravel middleware](http://laravel.com/docs/master/middleware). As a result anytime a request hits your application, the menu objects will be available to all your views.

```
php artisan make:middleware GenerateMenus
```

Be sure to also add the middleware to the `app\Http\Kernel.php`

```
    protected $middlewareGroups = [
        'web' => [
            //...
            \App\Http\Middleware\GenerateMenus::class,
        ],
        //...
    ];
```

Open the middleware you just created `app\Http\Middleware\GenerateMenus.php`

Then add a basic menu declaration. For example:

```
public function handle($request, Closure $next)
{
    \Menu::make('MyNavBar', function ($menu) {
        $menu->add('Home');
        $menu->add('About', 'about');
        $menu->add('Services', 'services');
        $menu->add('Contact', 'contact');
    });

    return $next($request);
}
```

Finally, open a view and add:

```
{!! $MyNavBar->asUl() !!}
```

Your menu will be created and displayed on the page.

**Note:** `$MyNavBar` is just a hypothetical name used in these examples; You may name your menus whatever you please.

In the above example `Menu::make()` creates a menu named `MyNavBar`, Adds the menu instance to the `Menu::collection` and ultimately makes `$myNavBar` object available across all application views.

This method accepts a callable inside which you can define your menu items. `add` method defines a new item. It receives two parameters, the first one is the item title and the second one is options.

The second parameter, `options`, can be a simple string representing a URL or an associative array of options and HTML attributes which we'll discuss shortly.

You can use `Menu::exists()` to check if the menu already exists.

```
Menu::exists('primary'); // returns false
Menu::make('primary', function(){});
Menu::exists('primary'); // returns true
```

You can use `Menu::makeOnce()` to ensure the make callback is only called if a menu by the given name does not yet exist. This can be useful if you are creating the same menu in multiple places conditionally, and are unsure whether other conditions have caused the menu to be created already.

```
Menu::makeOnce('primary', function(){}); // Creates primary, and executes callback.
Menu::makeOnce('primary', function(){}); // No operation.
```

**To render the menu in your view:**

`Laravel-menu` provides three rendering methods out of the box. However you can create your own rendering method using the right methods and attributes.

As noted earlier, `laravel-menu` provides three rendering formats out of the box, `asUl()`, `asOl()` and `asDiv()`. You can read about the details [here](#rendering-methods).

```
{!! $MyNavBar->asUl() !!}
```

You can also access the menu object via the menu collection:

```
{!! Menu::get('MyNavBar')->asUl() !!}
```

This will render your menu like so:

```

  Home
  About
  Services
  Contact

```

And that's all about it!

Routing
-------

[](#routing)

#### URLs

[](#urls)

You can simply assign a URL to your menu item by passing the URL as the second argument to `add` method:

```
$menu->add('About Us', 'about-us');
```

#### Named Routes

[](#named-routes)

`laravel-menu` supports named routes as well:

This time instead of passing a simple string to `add()`, we pass an associative with key `route` and a named route as value:

```
// Suppose we have these routes defined in our app/routes.php file

//...
Route::get('/',        ['as' => 'home.page',  function(){...}]);
Route::get('about',    ['as' => 'page.about', function(){...}]);
//...

// Now we make the menu:

Menu::make('MyNavBar', function($menu){

  $menu->add('Home',     ['route'  => 'home.page']);
  $menu->add('About',    ['route'  => 'page.about']);

});
```

#### Controller Actions

[](#controller-actions)

Laravel Menu supports controller actions as well.

You will just need to set `action` key of your options array to a controller action:

Suppose we have these routes defined in our `routes/web.php` or the older `app/Http/routes.php` file:

```
Route::get('services', 'ServiceController@index');
```

Then to refer to this route, we can pass the action into the options array.

```
$menu->add('services', ['action' => 'ServicesController@index']);
```

**Additionaly:** if you need to send some parameters to routes, URLs or controller actions as a query string, you can simply include them in an array along with the route, action or URL value:

```
Menu::make('MyNavBar', function($menu){

  $menu->add('Home',     ['route'  => 'home.page']);
  $menu->add('About',    ['route'  => ['page.about', 'template' => 1]]);
  $menu->add('services', ['action' => ['ServicesController@index', 'id' => 12]]);

  $menu->add('Contact',  'contact');

});
```

#### HTTPS

[](#https)

By default, the HTTP vs HTTPS will be determined by Laravel's UrlGenerator which matches the current schema of the page.

If you need to overwrite this behavior, call `secure()` on the item's `link` attribute to force https. Alternatively add key `secure` to the options array and set it to `true`:

```
$menu->add('Members', 'members')->link->secure();

// or alternatively use the following method

$menu->add('Members', ['url' => 'members', 'secure' => true]);
```

The output as `` would be:

```

    ...
    Members
    ...

```

Sub-items
---------

[](#sub-items)

Items can have sub-items too:

```
Menu::make('MyNavBar', function($menu){

  //...

  $menu->add('About',    ['route'  => 'page.about']);

  // these items will go under Item 'About'

  // refer to about as a property of $menu object then call `add()` on it
  $menu->about->add('Who We are', 'who-we-are');

  // or

  $menu->get('about')->add('What We Do', 'what-we-do');

  // or

  $menu->item('about')->add('Our Goals', 'our-goals');

  //...

});
```

You can also chain the item definitions and go as deep as you wish:

```
  $menu->add('About', ['route'  => 'page.about'])
       ->add('Level2', 'link address')
       ->add('level3', 'Link address')
       ->add('level4', 'Link address');
```

It is possible to add sub items directly using `parent` attribute:

```
$menu->add('About',    ['route'  => 'page.about']);
$menu->add('Level2', ['url' => 'Link address', 'parent' => $menu->about->id]);
```

Set Item's ID Manually
----------------------

[](#set-items-id-manually)

When you add a new item, a unique ID is automatically assigned to the item. However, there are time when you're loading the menu items from the database and you have to set the ID manually. To handle this, you can call the `id()` method against the item's object and pass your desired ID:

```
$menu->add('About', ['route' => 'page.about'])
     ->id('74398247329487')
```

Alternatively, you can pass the ID as an element of the options array when adding the menu item:

```
$menu->add('About', ['route' => 'page.about', 'id' => 74398247329487]);
```

Set Item's Nickname Manually
----------------------------

[](#set-items-nickname-manually)

When you add a new item, a nickname is automatically assigned to the item for further reference. This nickname is the camel-cased form of the item's title. For instance, an item with the title: `About Us` would have the nickname: `aboutUs`. However there are times when you have to explicitly define your menu items owing to a special character set you're using. To do this, you may simply use the `nickname()` method against the item's object and pass your desired nickname to it:

```
$menu->add('About', ['route' => 'page.about'])
     ->nickname('about_menu_nickname');

// And use it like you normally would
$menu->item('about_menu_nickname');
```

Alternatively, you can pass the nickname as an element of the options array:

```
$menu->add('About', ['route' => 'page.about', 'nickname' => 'about_menu_nickname']);

// And use it like you normally would
$menu->item('about_menu_nickname');
```

Referring to Items
------------------

[](#referring-to-items)

You can access defined items throughout your code using the methods described below.

#### Get Item by Title

[](#get-item-by-title)

Use $menu followed by the item's title in *camel case*:

```
$menu->itemTitleInCamelCase

// or

$menu->get('itemTitleInCamelCase')

// or

$menu->item('itemTitleInCamelCase')
```

As an example, let's insert a divider after `About us` item after we've defined it:

```
$menu->add('About us', 'about-us')

$menu->aboutUs->divide();

// or

$menu->get('aboutUs')->divide();

// or

$menu->item('aboutUs')->divide();
```

If you're not comfortable with the above method you can store the item's object reference in a variable for further reference:

```
$about = $menu->add('About', 'about');
$about->add('Who We Are', 'who-we-are');
$about->add('What We Do', 'what-we-do');
```

#### Get Item By Id

[](#get-item-by-id)

You can also get an item by Id if needed:

```
$menu->add('About', ['url' => 'about', 'id' => 12]);

$about = $menu->find(12)
```

#### Get All Items

[](#get-all-items)

```
$menu->all();

// or outside of the builder context

Menu::get('MyNavBar')->all();
```

The `all()` method returns a *Laravel Collection*.

#### Get the First Item

[](#get-the-first-item)

```
$menu->first();

// or outside of the builder context

Menu::get('MyNavBar')->first();
```

#### Get the Last Item

[](#get-the-last-item)

```
$menu->last();

// or outside of the builder context

Menu::get('MyNavBar')->last();
```

#### Get the Active Item

[](#get-the-active-item)

```
$menu->active()

// or outside of the builder content

Menu::get('MyNavBar')->active();
```

#### Get Sub-Items of the Item

[](#get-sub-items-of-the-item)

First of all you need to get the item using the methods described above then call `children()` on it.

To get children of `About` item:

```
$aboutSubs = $menu->about->children();

// or outside of the builder context

$aboutSubs = Menu::get('MyNavBar')->about->children();

// or

$aboutSubs = Menu::get('MyNavBar')->item('about')->children();
```

`children()` returns a *Laravel Collection*.

To check if an item has any children or not, you can use `hasChildren()`

```
if( $menu->about->hasChildren() ) {
    // Do something
}

// or outside of the builder context

Menu::get('MyNavBar')->about->hasChildren();

// Or

Menu::get('MyNavBar')->item('about')->hasChildren();
```

To get all descendants of an item you may use `all`:

```
$aboutSubs = $menu->about->all();
```

#### Get the Parent of the Item

[](#get-the-parent-of-the-item)

First get the item using one of the methods above then call `parent()` on it.

To get the parent of `About` item

```
$aboutParent = $menu->about->parent();

// or outside of the builder context

$aboutParent = Menu::get('MyNavBar')->about->parent();

// Or

$aboutParent = Menu::get('MyNavBar')->item('about')->parent();
```

To check if an item has a parent or not, you can use `hasParent()`

```
if( $menu->about->hasParent() ) {
    // Do something
}

// or outside of the builder context

Menu::get('MyNavBar')->about->hasParent();

// Or

Menu::get('MyNavBar')->item('about')->hasParent();
```

#### Magic Where Methods

[](#magic-where-methods)

You can also search the items collection by magic where methods. These methods are consisted of a `where` concatenated with a property (object property or even meta data)

For example to get an item with parent equal to 12, you can use it like so:

```
$subs = $menu->whereParent(12);
```

Or to get item's with a specific meta data:

```
$menu->add('Home',     '#')->data('color', 'red');
$menu->add('About',    '#')->data('color', 'blue');
$menu->add('Services', '#')->data('color', 'red');
$menu->add('Contact',  '#')->data('color', 'green');

// Fetch all the items with color set to red:
$reds = $menu->whereColor('red');
```

This method returns a *Laravel collection*.

If you need to fetch descendants of the matched items as well, Just set the second argument as true.

```
$reds = $menu->whereColor('red', true);
```

This will give all items with color red and their decsendants.

Referring to Menu Instances
---------------------------

[](#referring-to-menu-instances)

You might encounter situations when you need to refer to menu instances out of the builder context.

To get a specific menu by name:

```
$menu = Menu::get('MyNavBar');
```

Or to get all menus instances:

```
$menus = Menu::all();
```

You can also call `getCollection()` to get the same result:

```
$menus = Menu::getCollection();
```

Both methods return a *Laravel Collection*

HTML Attributes
---------------

[](#html-attributes)

Since all menu items would be rendered as HTML entities like list items or divs, you can define as many HTML attributes as you need for each item:

```
Menu::make('MyNavBar', function($menu){

  // As you see, you need to pass the second parameter as an associative array:
  $menu->add('Home',     ['route'  => 'home.page',  'class' => 'navbar navbar-home', 'id' => 'home']);
  $menu->add('About',    ['route'  => 'page.about', 'class' => 'navbar navbar-about dropdown']);
  $menu->add('services', ['action' => 'ServicesController@index']);
  $menu->add('Contact',  'contact');

});
```

If we choose HTML lists as our rendering format like `ul`, the result would be something similar to this:

```

  Home
  About
  Services
  Contact

```

It is also possible to set or get HTML attributes after the item has been defined using `attr()` method.

If you call `attr()` with one argument, it will return the attribute value for you. If you call it with two arguments, It will consider the first and second parameters as a key/value pair and sets the attribute. You can also pass an associative array of attributes if you need to add a group of HTML attributes in one step; Lastly if you call it without any arguments it will return all the attributes as an array.

```
//...
$menu->add('About', ['url' => 'about', 'class' => 'about-item']);

echo $menu->about->attr('class');  // output:  about-item

$menu->about->attr('class', 'another-class');
echo $menu->about->attr('class');  // output:  about-item another-class

$menu->about->attr(['class' => 'yet-another', 'id' => 'about']);

echo $menu->about->attr('class');  // output:  about-item another-class yet-another
echo $menu->about->attr('id');  // output:  id

print_r($menu->about->attr());

/* Output
Array
(
    [class] => about-item another-class yet-another
    [id] => id
)
*/

//...
```

You can use `attr` on a collection, if you need to target a group of items:

```
$menu->add('About', 'about');

$menu->about->add('Who we are', 'about/whoweare');
$menu->about->add('What we do', 'about/whatwedo');

// add a class to children of About
$menu->about->children()->attr('class', 'about-item');
```

Manipulating Links
------------------

[](#manipulating-links)

All the HTML attributes will go to the wrapping tags(li, div, etc); You might encounter situations when you need to add some HTML attributes to `` tags as well.

Each `Item` instance has an attribute which stores an instance of `Link` object. This object is provided for you to manipulate `` tags.

Just like each item, `Link` also has an `attr()` method which functions exactly like item's:

```
Menu::make('MyNavBar', function($menu){

  $about = $menu->add('About',    ['route'  => 'page.about', 'class' => 'navbar navbar-about dropdown']);

  $about->link->attr(['class' => 'dropdown-toggle', 'data-toggle' => 'dropdown']);

});
```

#### Link's Href Property

[](#links-href-property)

If you don't want to use the routing feature of `laravel-menu` or you don't want the builder to prefix your URL with anything (your host address for example), you can explicitly set your link's href property:

```
$menu->add('About')->link->href('#');

```

Active Item
-----------

[](#active-item)

You can mark an item as activated using `active()` on that item:

```
$menu->add('Home', '#')->active();

/* Output
 *
 * #
 *
 */
```

You can also add class `active` to the anchor element instead of the wrapping element (`div` or `li`):

```
$menu->add('Home', '#')->link->active();

/* Output
 *
 * #
 *
 */
```

Laravel Menu does this for you automatically according to the current **URI** the time you register the item.

You can also choose the element to be activated (item or the link) in `settings.php` which resides in package's config directory:

```
'active_element' => 'item',    // item|link
```

#### RESTful URLs

[](#restful-urls)

RESTful URLs are also supported as long as `restful` option is set as `true` in `config/settings.php` file, E.g. menu item with url `resource` will be activated by `resource/slug` or `resource/slug/edit`.

You might encounter situations where your app is in a sub directory instead of the root directory or your resources have a common prefix; In such case you need to set `rest_base` option to a proper prefix for a better restful activation support. `rest_base` can take a simple string, array of string or a function call as value.

#### URL Wildcards

[](#url-wildcards)

`laravel-menu` makes you able to define a pattern for a certain item, if the automatic activation can't help:

```
$menu->add('Articles', 'articles')->active('this-is-another-url/*');
```

So `this-is-another-url`, `this-is-another-url/and-another` will both activate `Articles` item.

#### Disable activation

[](#disable-activation)

Sometimes you may need to disable auto activation for single items. You can pass **disableActivationByURL** in options like this:

```
$menu->add('Anchor', ['disableActivationByURL' => true, 'url' => '#']);
```

This prevents auto activation by matching URL. But activation for items with active children keeps working.

Inserting a Separator
---------------------

[](#inserting-a-separator)

You can insert a separator after each item using `divide()` method:

```
//...
$menu->add('Separated Item', 'item-url')->divide()

// You can also use it this way:

$menu->('Another Separated Item', 'another-item-url');

// This line will insert a divider after the last defined item
$menu->divide()

//...

/*
 * Output as :
 *
 *
 *        ...
 *        Separated Item
 *
 *
 *        Another Separated Item
 *
 *        ...
 *
 *
 */
```

`divide()` also gets an associative array of attributes:

```
//...
$menu->add('Separated Item', 'item-url')->divide( ['class' => 'my-divider'] );
//...

/*
 * Output as :
 *
 *
 *        ...
 *        Separated Item
 *
 *
 *        ...
 *
 *
 */
```

Append and Prepend
------------------

[](#append-and-prepend)

You can `append` or `prepend` HTML or plain-text to each item's title after it is defined:

```
Menu::make('MyNavBar', function($menu){

  $about = $menu->add('About',    ['route'  => 'page.about', 'class' => 'navbar navbar-about dropdown']);

  $menu->about->attr(['class' => 'dropdown-toggle', 'data-toggle' => 'dropdown'])
              ->append(' ')
              ->prepend(' ');

  // ...

});
```

The above code will result:

```

  ...

      About

```

You can call `prepend` and `append` on collections as well.

Before and After
----------------

[](#before-and-after)

Allows you to add an arbitrary html block instead of a drop-down list. And many other possibilities. Unlike `append` and `prepend`, `before` and `after` adds an arbitrary html to the root of the tag li.

```
Menu::make('MyNavBar', function($menu){

  $menu->add('User', ['title' => Auth::user()->name, 'class' => 'nav-item'])
      ->after(view('layouts.pattern.menu.user_info'))
      ->link->attr([
          'class'         => 'nav-link dropdown-toggle',
          'data-toggle'   => 'dropdown',
          'role'          => 'button',
          'aria-expanded' => 'false',
      ]);

  // ...

});
```

Resource of view, pattern: layouts.pattern.menu.user\_info

```

        name; ?>
