Code Monkey home page Code Monkey logo

menu's Introduction

Html Menu Generator

Latest Version on Packagist Tests Total Downloads

The spatie/menu package provides a fluent interface to build menus of any size in your php application. If you're building your app with Laravel, the spatie/laravel-menu provides some extra treats.

If you're looking for a more flexible and renderless solution, maybe our spiritual successor Laravel Navigation is what you're looking for.

Documentation is available at https://docs.spatie.be/menu.

Upgrading from version 1? There's a guide for that!

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Human Readable, Fluent Interface

All classes provide a human readable, fluent interface (no array configuration). Additionally, you can opt for a more verbose and flexible syntax, or for convenience methods that cover most use cases.

Menu::new()
    ->add(Link::to('/', 'Home'))
    ->add(Link::to('/about', 'About'))
    ->add(Link::to('/contact', 'Contact'))
    ->add(Html::empty())
    ->render();

// Or just...
Menu::new()
    ->link('/', 'Home')
    ->link('/about', 'About')
    ->link('/contact', 'Contact')
    ->empty()
<ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
    <li><a href="/contact">Contact</a></li>
    <li></li>
</ul>

Or a More Programmatic Approach

Menus can also be created through a reduce-like callable.

$pages = [
    '/' => 'Home',
    '/about' => 'About',
    '/contact' => 'Contact',
];

Menu::build($pages, function ($menu, $label, $url) {
    $menu->add($url, $label);
})->render();
<ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
    <li><a href="/contact">Contact</a></li>
</ul>

Strong Control Over the Html Output

You can programatically add html classes and attributes to any item in the menu, or to the menu itself.

Menu::new()
    ->addClass('navigation')
    ->add(Link::to('/', 'Home')->addClass('home-link'))
    ->add(Link::to('/about', 'About'))
    ->add(Link::to('/contact', 'Contact')->addParentClass('float-right'))
    ->wrap('div.wrapper')
<div class="wrapper">
    <ul class="navigation">
        <li><a href="/" class="home-link">Home</a></li>
        <li><a href="/about">About</a></li>
        <li class="float-right"><a href="/contact">Contact</a></li>
    </ul>
</div

Adding id to elements

You can add id, so you can easily target some of these elements with CSS or JS.

Menu::new()
    ->id('navigation')
    ->add(Link::to('/', 'Home')->id('home-link'))
    ->add(Link::to('/about', 'About'))
    ->add(Link::to('/contact', 'Contact'))
<ul id="navigation">
    <li><a href="/" id="home-link">Home</a></li>
    <li><a href="/about">About</a></li>
    <li><a href="/contact">Contact</a></li>
</ul>

Not Afraid of Depths

The menu supports submenus, which in turn can be nested infinitely.

Menu::new()
    ->link('/', 'Home')
    ->submenu('More', Menu::new()
        ->addClass('submenu')
        ->link('/about', 'About')
        ->link('/contact', 'Contact')
    );
<ul>
    <li><a href="/">Home</a></li>
    <li>
        More
        <ul class="submenu">
            <li><a href="/about">About</a></li>
            <li><a href="/contact">Contact</a></li>
        </ul>
    </li>
</ul>

Some Extra Treats for Laravel Apps

The Laravel version of the menu package adds some extras like convenience methods for generating URLs and macros.

Menu::macro('main', function () {
    return Menu::new()
        ->action('HomeController@index', 'Home')
        ->action('AboutController@index', 'About')
        ->action('ContactController@index', 'Contact')
        ->setActiveFromRequest();
});
<nav class="navigation">
    {{ Menu::main() }}
</nav>

Spatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects on our website.

Install

You can install the package via composer:

composer require spatie/menu

Usage

Documentation is available at https://docs.spatie.be/menu.

Upgrading to 2.0

Upgrading to 2.0 should be pretty painless for most use cases.

If you're just building menus...

  • The void and voidIf have been removed. These can be replaced by html and htmlIf, with empty strings as their first arguments
  • The prefixLinks and prefixUrls methods have been removed because they were too unpredictable in some case. There currently isn't an alternative for these, besides writing your own logic and applying it with applyToAll.

If you're using custom Item implementations...

  • The HtmlAttributes and ParentAttributes traits have been renamed to HasHtmlAttributes and HasParentAttributes.
  • The HasUrl interface and trait has been removed. Url-related methods now also are part of the Activatable interface and trait.

New features...

  • Added the static Menu::build and non-static Menu::fill methods to create menu's from arrays.
  • The setActive method on Activatable now also accepts a non-strict boolean or callable parameter to set $active to true or false.
  • Menu::html and Menu::htmlIf now accept a $parentAttributes array as their second arguments.

Changelog

Please see CHANGELOG for more information what has changed recently.

Testing

phpunit

Contributing

Please see CONTRIBUTING for details.

Security

If you've found a bug regarding security please mail [email protected] instead of using the issue tracker.

Postcardware

You're free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.

Our address is: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium.

We publish all received postcards on our company website.

Credits

License

The MIT License (MIT). Please see License File for more information.

menu's People

Contributors

adrianmrn avatar akoepcke avatar alexbowers avatar ayoobmh avatar backendtea avatar buddhacode avatar carusogabriel avatar ccsliinc avatar chris53897 avatar daison12006013 avatar davidjr82 avatar erikn69 avatar frankperez87 avatar freekmurze avatar joucke avatar mansoorkhan96 avatar markwalet avatar matthewtrask avatar milwad-dev avatar mrk-j avatar nielsvanpach avatar patinthehat avatar peter279k avatar pimlie avatar ralphjsmit avatar rojtjo avatar rubenvanassche avatar sebastiandedeyne avatar svenluijten avatar swapnilsarwe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

menu's Issues

submenu rendenring only in a menu parts

Imagine we have a menu like this

root
  |_ A
    |_ A.1
    |_ A.2
      |_ A.2.1
  |_ C
    |_ C.1
  |_ D

We already detect with $menu->setActiveFromRequest or $menu->setActive the current active element in the menu. We should be able to see if we are on item "A.2.1" that A.2 is active (as parent) and A is active (as parent) too. But we can do more like non rendering item in C.1 because is in submenu not active at all.

So we can imagine to have a $menu->setActiveClassOnParent('css class for rendering parent menu from submenu') (pretty the same as setActiveClass). And a $menu->submenuIfActiveElement(...) (like$menu->submenuIf() but with condition that the child element must be selected or itself to be rendered)

I think it could be a nice improvements.

[Question] Is it possible to build submenues with a multidimensional array?

Is it possible to render a menu with something similar to this array?

$pages = [
    'Home' => '/',
    'About' => [ // About submenu
        'About Us' => '/about/us',
        'Contact' => '/about/contact',
        'Locations' => [ // Another submenu
             'Location 1' => '/about/location/1',
             'Location 2' => '/about/location/2',
        ]
    ],
    'Profile' => '/profile',
];

addClass methods for View::Create()

I am currently trying to get a complex menu work with this package. Package works create but for my personal menu I grab to the raw method to often so I tried to refactor it and use the default functions included.

However as soon as I am using the View::create() method I cannot style the <li> surrounding that view creation. When I do:

      $this->menu->add(
            View::create('partials.menu.link', [
                'name' => $name,
                'icon' => $icon,
                'url' => $url
            ])
            ->addClass('kt-menu__item')
            ->setAttribute('aria-haspopup', 'true')
        )

I get the error addClass and setAttribute does not exist.
When I had those methods one level up (after the add method) they are appended to the parent ul. How can give styling to the li where a view created the content of that li?

Am I missing something here?

Consistency in README and CONTRIBUTION

The contributionguide says you have to execute composer test for testing and the readme file says phpunit. Which one do you prefer?

I can make a pull request if you have made a decision. This isn't the most complicated change ;)

2 Menus with Active item synced on both doesn't work

Hello.

I've built 2 menus.
1st, the Main, with Areas names at the top of the site.
2nd, a Menu that only appears in one Area,

I'm trying to do the following.
If I visit the area where the 2nd menu is at, the 1st Menu should show as active the Area link. Regardless of witch sub-area I'm at.

But it doesn't.

Any suggestions?

Renderer class - decoupled from Menu

Menus are something very special, like nearly all frontend/display things.
There are some common structures that cover ~90% but in all other cases I have to override the Menu and can Just have one render style.

If I think about dashboards you have one sidebar menu, one in the top navbar and one in the footer.

With a dedicated render class that would be a lot easier.

$menu = new Menu(); // create the menu with items
$menu->render(); // default one
$menu->render('bootstrap-3'); // bootstrap3 renderer
$menu->render('dropdown'); // dropdown renderer

This would be easy achievable by an Interface for renderers and the manager-driver approach that's massively used in laravel. By this it would be possible to create ready to use renderers in foreign packages and just register them.

It will also help to remove addClass for all items if all need .item. And enable icons in the menu and to add bootstrap .caret and all the other stuffs.

I would be fine to create a PR for this, just want to know if it is wanted and the way to solve the Problem ist ok!?

Related to:

Submenu: Move <ul> of submenu to the same <li> element of the parent

According to this documentation https://getuikit.com/docs/nav I need to get the following structure:

<div class="uk-width-1-2@s uk-width-2-5@m">
    <ul class="uk-nav-default uk-nav-parent-icon" uk-nav>
        <li class="uk-active"><a href="#">Active</a></li>
        <li class="uk-parent">
            <a href="#">Parent</a>
            <ul class="uk-nav-sub">
                <li><a href="#">Sub item</a></li>
                <li>
                    <a href="#">Sub item</a>
                    <ul>
                        <li><a href="#">Sub item</a></li>
                        <li><a href="#">Sub item</a></li>
                    </ul>
                </li>
            </ul>
        </li>
        <li class="uk-parent">
            <a href="#">Parent</a>
            <ul class="uk-nav-sub">
                <li><a href="#">Sub item</a></li>
                <li><a href="#">Sub item</a></li>
            </ul>
        </li>
    </ul>
</div>

So I need:

<ul>
	<li><a href="">Test</a>
		<ul>
			<li><a href="">Test</a></li>
		</ul>
	</li>
</ul>

(ul of the submenu is in the same li element as the parent)

If I follow https://docs.spatie.be/menu/v2/basic-usage/adding-items#submenus, I get this result:

<ul>
    <li>
        <a href="/">Menu</a>
    </li>
    <li>
        <ul>
            <li>
                <a href="/basic-usage/your-first-menu">
                    Your First Menu
                </a>
            </li>
            <li>
                <a href="/basic-usage/adding-submenus">
                    Adding Submenus
                </a>
            </li>
        </ul>
    </li>
</ul>

which is

<ul>
	<li>
		<a href="">Test</a>
	</li>
	<li>
		<ul>
			<li>
				<a href="">Test</a>
			</li>
		</ul>
	</li>
</ul>

You can see: ul is in an extra row here.

How can I deal with that?

Exception when prepend is instance of Item

I'm experiencing an issue with the following four lines.

menu/src/Menu.php

Lines 720 to 724 in 926c8f2

if ($this->prepend instanceof Item && $this->prepend->isActive()) {
$this->prepend = $this->renderActiveClassOnLink($this->prepend);
}
$menu = $this->prepend.$wrappedContents.$this->append;

The issue occurs when $this->prepend contains a Spatie\Menu\Html instance. This object implements the Item interface, and L720 makes me believe this should be valid. However, the render method concats the item into a string, triggering the __toString() method, which does not exist on the Item interface.

Hence I end up with the following exception:

Object of class Spatie\Menu\Html could not be converted to string

I think the easiest solution would be to check if $this->prepend is an item, and then call ->toHtml()->render() on it. Should I open a PR for this, or am I missing something else?

[Question] Bootstrap 4 style

Hello,
I was wondering how can i set a nav element instead of the ul and also usa an a element instead of a li. The menu that i want look like that :

<nav class="nav nav-menu flex-column">
    <a class="nav-link active" href="#">
        <i class="fa fa-user"></i> Account
    </a>
    <a class="nav-link" href="#">
        <i class="fa fa-bell-o"></i> Notifications
    </a>
</nav>

I saw nothing about that in the doc.

Submenu active header

I hope this is an easy fix. I have no idea where to search for a solution at this time.

->submenu(
    Link::to('#', 'Contacts')
        ->addClass('btn btn-outline dropdown-toggle mr-2')
        ->setAttributes(['data-toggle' => 'dropdown', 'role' => 'button']),
        Menu::new()
            ->addClass('dropdown-menu')
            ->route('admin.customer.index', 'Customers')
            ->route('admin.supplier.index', 'Suppliers')
            ->wrap('div', ['class' => 'dropdown'])
            ->setActiveClassOnLink()
            ->setActiveFromRequest()
            ->each(function (Link $link) {
                $link->addClass('dropdown-item');
            })
)

This is generates the following menu:

<div class="dropdown">
  <a href="#" data-toggle="dropdown" role="button" class="btn btn-outline dropdown-toggle mr-2">Contacts</a>
  <ul class="dropdown-menu active">
    <li class="active exact-active"><a href="/admin/customers" class="dropdown-item active exact-active">Customers</a></li>
    <li><a href="/admin/suppliers" class="dropdown-item">Suppliers</a></li>
  </ul>
</div>

But no matter what I try, I can't get the Contacts link (with href="#") to become active.

I have tried changing the url structure of /admin/customers and /admin/suppliers to /admin/contacts/customers and /admin/contacts/suppliers and changed # to /admin/contacts, but that didn't work.

I also tried things with addParentClass but because it isn't a parent, that doesn't work.

What am I doing wrong or what am I missing?

Make the Menu class serializable

Use Case:

I am trying to make my application faster, and generating the menu every time seems like a waste of time, so I would like to cache it.

Problem:

The Menu class isn't serializable so it can't be cached.

Solution:

Make the Menu class and its subclasses serializable.

Reordering through different manipulations

Hi neighbours (I'm dutch hehe :)),

I wonder if this library supports ordering items after they have been added.

My usecase: through different ServiceProviders I'd like to add links after another specific link.

I couldn't manage this one yet, hopefuly there is a possibility to make this work!

Regards, Bob

How to create a dynamic multilevel menu using data source ?

Is it possible to create a dynamic multilevel menu from the data source? The below data is a return from the database.

0 => array:10 [▼
    "id" => 1
    "menu_id" => 1
    "menu_name" => "politics"
    "menu_slug" => "politics"
    "menu_type" => "category"
    "parent_id" => 0
    "menu_order" => 1
    "created_at" => "2020-10-12T04:06:05.000000Z"
    "updated_at" => "2020-10-12T04:06:05.000000Z"
    "children" => array:1 [▼
      0 => array:9 [▼
        "id" => 2
        "menu_id" => 1
        "menu_name" => "social"
        "menu_slug" => "social"
        "menu_type" => "category"
        "parent_id" => 1
        "menu_order" => 2
        "created_at" => "2020-10-12T04:06:05.000000Z"
        "updated_at" => "2020-10-12T04:25:48.000000Z"
      ]
    ]
  ]
  1 => array:10 [▼
    "id" => 3
    "menu_id" => 1
    "menu_name" => "finance"
    "menu_slug" => "finance"
    "menu_type" => "category"
    "parent_id" => 0
    "menu_order" => 3
    "created_at" => "2020-10-12T04:06:05.000000Z"
    "updated_at" => "2020-10-12T04:06:05.000000Z"
    "children" => []
  ]

Update for Bootstrap 4

Hi there,

We are using spatie/laravel-menu and therefore spatie/menu in a project that is using Bootstrap 4. In Bootstrap 4 the markup for dropdowns changed, they are not using an <ul> for dropdowns anymore. We made quick fix to enable us to use a <div> instead of an <ul> and not wrap the links in an <li>.

If we create some tests and update the documentation accordingly, are you willing to merge this?

Thanks in advance 👍

Allow filters and manipulators to be invokable classes

When manipulating items according to https://docs.spatie.be/menu/v2/items-in-depth/manipulating-items, it would be nice to allow invokable classes (which already pass the callable typehint) as well as closures and function.

Currently, this is not allowed because ReflectionFunction($callable) is used, which does not accept an object in the constructor.

I am opening a PR to patch this, but wanted an issue first to make sure everything is nice and tidy.

Add class to <li> with submenu

When I using submenu() function to create submenu, I need to add class to li like:

<ul>
  <li><a href="#">Home</a></li>
  <li class="submenu">
    <a href="#">Submenu</a>
    <ul>...</ul>
  </li>
</ul>

Link Target

Hello.
I can't seem to find on the documentation how to set a link's target.
Is it possible?

ItemClass from parent menu cascades into submenu wrapper

Not easy to explain but it seems the addItemClass() from a menu gets applied to the container of the submenu.

An example is worth a thousand words... example Bootstrap 4 styled menu and submenu:

Menu::new()
    ->addClass('nav')
    ->addItemParentClass('nav-item')
    ->addItemClass('nav-link')

    ->link('#', 'Main Menu Link 1')
    ->link('#', 'Main Menu Link 2')
    ->submenu(
        Link::to('#', 'Sub Menu')
            ->addClass('nav-link nav-dropdown-toggle')
        ,
        Menu::new()
            ->addClass('nav-dropdown-items') // this has nav-link class from parent menu but it shouldn't
            ->addParentClass('nav-dropdown')
            ->addItemParentClass('nav-item')
            ->addItemClass('nav-link')
            ->link('#', 'Sub Menu Item 1')
            ->link('#', 'Sub Menu Item 2')
    );

This HTML is generated:

<ul class="nav">
    <li class="nav-item"><a href="#" class="nav-link">Main Menu Link 1</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Main Menu Link 2</a></li>
    <li class="nav-dropdown nav-item"><a href="#" class="nav-link nav-dropdown-toggle">Sub Menu</a>
        <ul class="nav-dropdown-items nav-link">
            <li class="nav-item"><a href="#" class="nav-link">Sub Menu Item 1</a></li>
            <li class="nav-item"><a href="#" class="nav-link">Sub Menu Item 2</a></li>
        </ul>
    </li>
</ul>

This is what should be generated:

<ul class="nav">
    <li class="nav-item"><a href="#" class="nav-link">Main Menu Link 1</a></li>
    <li class="nav-item"><a href="#" class="nav-link">Main Menu Link 2</a></li>
    <li class="nav-dropdown nav-item"><a href="#" class="nav-link nav-dropdown-toggle">Sub Menu</a>
        <ul class="nav-dropdown-items">
            <li class="nav-item"><a href="#" class="nav-link">Sub Menu Item 1</a></li>
            <li class="nav-item"><a href="#" class="nav-link">Sub Menu Item 2</a></li>
        </ul>
    </li>
</ul>

Menu::wrap wraps menu and link element in Menu::submenu

$menu_a = Menu::new()
->link( '#', 'SubMenu Item 1' )
->link( '#', 'SubMenu Item 2' )
->link( '#', 'SubMenu Item 3' )
->wrap( 'div', ['class' => 'someclass'] );

$menu = Menu::new()
->link( '#', 'Menu Item 1' )
->link( '#', 'Menu Item 2' )
->submenu( Link::to( '#', 'Menu Item 3' ), $menu_a );

echo $menu->render();

Outputs

<ul>
    <li><a href="#">Menu Item 1</a></li>
    <li><a href="#">Menu Item 2</a></li>
    <li>
        <div class="someclass"><a href="#">Menu Item 3</a>
            <ul>
                <li><a href="#">SubMenu Item 1</a></li>
                <li><a href="#">SubMenu Item 2</a></li>
                <li><a href="#">SubMenu Item 3</a></li>
            </ul>
        </div>
    </li>
</ul>

Should Output

<ul>
    <li><a href="#">Menu Item 1</a></li>
    <li><a href="#">Menu Item 2</a></li>
    <li>
        <a href="#">Menu Item 3</a>
        <div class="someclass">
            <ul>
                <li><a href="#">SubMenu Item 1</a></li>
                <li><a href="#">SubMenu Item 2</a></li>
                <li><a href="#">SubMenu Item 3</a></li>
            </ul>
        </div>
    </li>
</ul>

Adding active class on wrapper element

I have a situation with submenu where I need to add custom active class on wrapper element (default element is 'ul') to show submenu items on page when one of submenu items is clicked.

Currently, this package add active class on parent 'li' element but not on 'ul'.

How would you handle it?

I have this:

<ul class='menu'>
  <li class='active'>
    <a href='#'>Dropdown</a>
    <ul>
      <li class='active'>Submenu item 1</li>
      <li>Submenu item 2</li>
    </ul>
  </li>
</ul>

But I need this:

<ul class='menu'>
  <li class='active'>
    <a href='#'>Dropdown</a>
    <ul class='show'>
      <li class='active'>Submenu item 1</li>
      <li>Submenu item 2</li>
    </ul>
  </li>
</ul>

'show' class on submenu wrapper 'ul' element.

Thanks!

Laravel integration ?

Hello,
I'm not very comfortable with Laravel.

I wonder how to integrate your menu laravel and in the view blade?

Would you do a little tutorial on the subject?

PHP 5.6 support

Hi fellow Antwerpenaar,

Thanks for this great package!
I was wondering if it would be difficult to make this library work in PHP 5.6?

Render as JSON

I have a case where I don't want a fully formatted menu from the back-end. I really like how easy and fluent it is to build menu with this library, but it seems that I can only export menus in HTML.

I would love for the following code to render as the following JSON instead of HTML:

Menu::new()
    ->submenu('main', Menu::new()
        ->add(Link::to('/dashboard', 'dashboard')))
;
[{
  "name": "menu",
  "links": [{
    "url": "/dashboard",
    "text": "dashboard"
  }]
}]

Currently, it can only be rendered as this HTML:

<ul>
    <li>main
        <ul>
            <li><a href=\"/dashboard\">dashboard</a></li>
        </ul>
    </li>
</ul>

Maybe kind of related to #62?


I've made my own lib to do this.

Active menu item is not hightliting

Hello,

I have a problem where my active menu item is not being set properly

this is my menu on http://localhost/geofence/assign :

image

this is my routes

| URI                                                       | Name                 |
| geofence                                                  | geofence.index       |
| geofence/assign                                           | geofence.assign      |
| geofence/show                                             | geofence.show        |

this my code

$this->createSubMenu('Geofence', 'fa fa-globe')
              ->routeIfCan(['view', Geofence::class],'geofence.index','<i class="fa fa-pencil-square-o"></i> <span>CRUD</span></a>')
              ->route('geofence.assign','<i class="fa fa-street-view"></i> <span>Assign</span></a>')
              ->route('geofence.show','<i class="fa fa-list"></i> <span>Contacts List</span></a>')
              ->setActiveFromRequest();

protected function createSubMenu($text = '', $iconClass =''){
    return Menu::new()->wrap('li', ['class' => 'treeview'])
              ->prepend('
                <a href="#">
                  <i class="'.$iconClass.'"></i>
                  <span>'. $text .'</span>
                  <span class="pull-right-container">
                  <i class="fa fa-angle-left pull-right"></i>
                  </span>
                </a>
              ')
              ->addClass('treeview-menu');
}

[Question] Controlling sub-menu visibility based on children.

With addif() I can control if a menu is shown or not, and it works great. But I'm finding myself having sub-menu title/element without any children. So my question is: is there a way that I hide the sub-menu title/element when it does not have any children?

Something like this (let's take C as our test subject).
Scenario 1: all elements exists.

root
  |_ A
    |_ A.1
    |_ A.2
  |_ C
    |_ C.1
  |_ D

Scenario 2: addIf(false, C.1), therefore C does not exist either.

root
  |_ A
    |_ A.1
    |_ A.2
  |_ D

Thanks!

Templates

What are your recommendations for theming the menu? Are they at Bootstrap standards? I think most of the work for a menu is the UI itself, but might differ due to complexity of course. It would be nice with some features or integrations to other libraries where I can easily output a Bootstrap topnavbar or left/right menu.

Thanks for all your open source stuff btw, it's amazing!

[Suggestion] Fluent API for considering authorization

Something like:

Menu::new()
    ->link('/', 'Home')
    ->linkIfCan('/products', 'Products', 'review_products');
    ->linkIfCan('/inventory', 'Inventory', ['check_inventory', 'update_inventory']);

Nice package by the way 👍

Link segment method missing

after upgrade to spatie/menu 2.0.1

I've a setActive logic:

->setActive(function (Link $link) {
            if($link->segment(2) == Request::segment(2)){
                return Request::url();
            }
})

ErrorException: Method segment does not exist.

Option to set active class to link element

I believe that the ability to set the active class on the link element itself should be added. If it's already possible and I just overlooked the functionality I apologize, but I haven't seen an obvious way how to do it yet.

This would be useful whether it's implemented as an explicit feature or an implicit feature of using the withoutParentTag method. After spending some time debugging why my menu's active links weren't set I think I chased it down to using that method.

I am using Bulma.css, so the navbar menus are just plain anchor tags meaning I use withoutParentTag. So the issue I'm having is that the active class setting feature becomes useless since it applies to the parents by default.

Current Output:
Route: /blog

<div class="navbar-end">
<a href="/" class="navbar-item">Home</a>
<a href="/blog" class="navbar-item">Blog</a>
<a href="/about" class="navbar-item">About</a>
</div>

Expected Output:
Route: /blog

<div class="navbar-end">
<a href="/" class="navbar-item">Home</a>
<a href="/blog" class="navbar-item is-active">Blog</a>
<a href="/about" class="navbar-item">About</a>
</div>

Current Output w/ Parents:
Route: /blog

<div class="navbar-end">
<li><a href="/" class="navbar-item">Home</a></li>
<li class="is-active"><a href="/blog" class="navbar-item">Blog</a></li>
<li><a href="/about" class="navbar-item">About</a></li>
</div>

Modernise package

  • Drop StyleCI
  • Drop Travis
  • Use GitHub workflows
  • Update badges in readme
  • Drop anything below PHP 7.4
  • Use PHP 7.4 where possible
  • Make sure testsuite runs
  • Tag new version

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.