Html menu generator for Laravel

Overview

Html Menu Generator for Laravel

Latest Version on Packagist Software License Test Status Code Style Status Total Downloads

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

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

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

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.

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.

Installation

You can install the package via composer:

composer require spatie/laravel-menu

Usage

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

Changelog

Please see CHANGELOG for more information what has changed recently.

Testing

$ phpunit

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

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

Comments
  • [PROPOSAL] AddView

    [PROPOSAL] AddView

    I did not find an easy way to add a view to the menu.

    I am thinking about using this package and I have some more complicated menu items, that are more than just a link. I store those items in separate views, which is why adding a view as a menu item would be good.

    Maybe something like this:

    Menu::new()
      ->action('HomeController@index', 'Home')
      ->addView('menu.viewFile', $viewData);
    

    I think currently it would be possible to pass a view('menu.viewFile', $viewData)->render() to the add() method? But I think this would be a nicer way to add it.

    Of course I just realise, that setActiveFromRequest would not work with a rendered view, would it? This would possible make it even more useful, as some logic for this could be included.

    opened by lukasoppermann 22
  • Wrap around <ul> only

    Wrap around

    Got pretty much everything working. Thanks for the package!

    One small issue with dropdown using UIKit. When I use ->submenuIf() and have ->wrap('div', ['class' => 'uk-navbar-dropdown']), it adds it around the <a> as well which I don't want. Any way to do that? Tried quite a few different ideas but none worked.

    Menu::macro('main', function() {
        $menu = Menu::new()
            ->addClass('uk-navbar-nav')
            ->setActiveClass('uk-active')
            ->route('home', 'Home')
            ->submenuIf($isAdmin, '<a href="#">Admin</a>', function (Spatie\Menu\Laravel\Menu $menu) {
                $menu
                    //->wrap('div', ['class' => 'uk-navbar-dropdown'])
                    ->addClass('uk-nav uk-navbar-dropdown-nav')
                    ->route('admin.item', 'Item')
                    ->route('admin.item2', 'Item 2')
                ;
            })
            ->setActiveFromRequest()
        ;
    
        return $menu;
    });
    

    Need this format;

    <li>
        <a href="#">Parent</a>
        <div class="uk-navbar-dropdown">
            <ul class="uk-nav uk-navbar-dropdown-nav">
                <li><a href="#">Item</a></li>
                <li><a href="#">Item</a></li>
            </ul>
        </div>
    </li>
    
    opened by bbashy 9
  • [PROPOSAL] AddArray method

    [PROPOSAL] AddArray method

    Hey,

    as I am starting to use the package, it noticed that it would be pretty handy to be able to loop over an array. Pretty often menu items will be stored in a config file or a database and retrieved in one set. While it is possible to achieve this by hand or using a macro, I think it would be a valuable addition to the package (probably added to the main package, nor the Laravel version).

    To allow for as much flexibility and little code, I would suggest to add a method that takes an array and a callable as parameters, the callable gets the $key and $value and needs to return an Item.

    I used the macro function to build a "prototype" but I think it would be much better to include this into the default build.

    Menu::macro('addArray', function(array $array, callable $callable){
        foreach($array as $key => $value)
        {
            $this->add($callable($value, $key));
        }
        return $this;
    });
    
    // will be use like this:
    
    return Menu::new()
        ->addArray([
            [
                'link' => '/link',
                'name' => 'Link'
            ],
            [
                'link' => '/link-2',
                'name' => '2nd Link'
            ],
        ], function($item){
            return Link::to($item['link'], $item['name']);
        });
    
    opened by lukasoppermann 8
  • [QUESTION] Bootstrap-style submenu's

    [QUESTION] Bootstrap-style submenu's

    • [x] I have read and understood the contributors guide.
    • [X] I have checked the pull requests tab for existing solutions/implementations to my issue/suggestion.
    • [X] I have checked that the bug-fix I am reporting can be replicated.

    Description of the problem

    I am struggling to get submenu's working with Bootstrap 3 navbar's. It simply boils down to this: the examples you provide generate submenu's in a separate <li>, while Bootstrap expects you to add a submenu right after the anchor, within the same <li> of the parent.

    Laravel-menu generates:

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

    While Bootstrap expects:

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

    In order to generate the second code fragment using laravel-menu, I would expect something like this in PHP:

    Menu::new()->add(Link::to('/', 'item'), Menu::new()
        ->add(Link::to('/sub', 'subitem'))
    );
    

    Is there something I missed? Or are there any plans in making this work, making Bootstrap submenu's possible?

    Steps to reproduce

    I have used the submenu code examples from the documentation.

    opened by thijskok 8
  • [Feature Request] Add items to tagged positions

    [Feature Request] Add items to tagged positions

    Dear Spatie team,

    First of all thank you for all your hard work 👏.

    I've been playing with laravel-menu for a bit now and figured out how to add items to the same menu from various sources:

    • I added a 'test' link from within the Laravel app
    • I added a 'package' link from within a custom Laravel package

    I'm wondering if it would be useful, and in the scope of this package, to be able to add a menu item to a tagged position.

    Painting a picture: let's say you are building your own docs sidebar menu. You could optionally "tag" a position called "Basic Usage". From anywhere in your code you could fetch your menu with app('menu.docs.sidebar) (pseudo-code) and ->link('random-link', 'Random Link');. This would prepend the "Random Link" item to the sidebar menu, specifically under the "Basic Usage" list.

    If this is already possible I've must've skipped the docs on that part. If this is not possible, I'd love to collaborate on the solution and possibly provide a Pull Request, if and when required.

    Thank you for looking into this, and I'd love hearing from you.

    Tom

    enhancement help wanted 
    opened by ttomdewit 7
  • How to use a generated menu in all views

    How to use a generated menu in all views

    Hi there, new to Laravel (5.4)

    I've created a basic menu. To test, I placed the code in my HomeController but obviously rendering only works in the view called in the controller.

    My blade structure is as follow home.blade -> @extends('layouts.blank') blank.blade -> @include('includes/sidebar') sidebar.blade -> contains {!! Menu::main() !!}

    So when I'm using home I can see the menu but any other view that extends blank doesn't render the menu.

    Where can I use a basic menu defined like that

    $menu = Menu::new([
        Link::to('/', 'Home'),
        Link::to('/about', 'About'),
    ]);
    

    and have it available in all views? Probably a service controller or a middleware but to be honest since I'm new to Laravel I don't have a clue.

    Thanks.

    opened by uovidiu 6
  • [IMPROVEMENT] Menu class should implement Htmlable

    [IMPROVEMENT] Menu class should implement Htmlable

    • [x] I have read and understood the contributors guide.
    • [x] I have checked that another pull request for this purpose does not exist.
    • [x] I have considered, and confirmed that this submission will be valuable to others.
    • [x] I have added tests to prove that the code in this PR works.

    Description

    If the Menu class implements the Illuminate\Contracts\Support\Htmlable interface, it will be possible to use the standard ``{{ $var }}syntax in Blade, as opposed to the{!! $var !!}` syntax.

    Which means you may now output the menu by doing...

    {{ $menu }}
    

    ... which in my opinion looks less hacky.

    This is a minor improvement, but a good one (and a simple one), in my opinion.

    This PR does three things:

    • Adds "implements Htmlable" to the Menu class, plus a use at the top,
    • Adds a toHtml method which returns $this->render() to satisfy the Htmlable interface,
    • Adds illuminate/contracts to require-dev in the composer.json (so that Travis doesn't fail)
    • And adds a test.
    opened by kalfheim 6
  • The sub menu child item cannot be activated

    The sub menu child item cannot be activated

    Menu::new()
    ->add(...)
    ->submenu(
                            Menu::new()
                                ->prepend('<a data-toggle="collapse" href="#safety_management"><i class="ti-lock"></i><p>安全管理<b class="caret"></b></p></a>')
                                ->addClass('collapse nav')
                                ->setAttribute('id', 'safety_management')
                                ->link('/user/change-password', '<span class="sidebar-mini">&nbsp;</span><span class="sidebar-normal">修改密码</span>')
    //                            ->setActive('/user/change-password')   //running
                                ->setActive(function (Link $link) {
                                   dd($link);    //Not running           
    
                                    return $link->url() === explode('?', Request::getRequestUri())[0];
                                })
                        )
    
    
    opened by hookover 5
  • Add activateForPath method

    Add activateForPath method

    Hey @sebastiandedeyne,

    as you might have noticed, I am using views for all my menu items. While I understand that this might not be the case for your projects, I think it is a very likely case for things like:

    • profile links with (img) Name
    • links prefixed with an inline/use svg
    • links which have Additional elements, e.g. a list of links with a delete link on them as well

    ... and many more.

    I do understand you do not want to alter and/or mess up the api, so something like View::create('/link','view.name') is out of the question.

    My proposal would be to add a function activateForPath which could be used to set the link that should trigger the activation of a menu item.

    The usage would be like this:

    View::create('view.name')->activateForPath('/link');
    

    I think, all it would need to do would be the following:

    public function activateForPath($path)
    {
        if(app('request')->path() === trim($path,'/')){
            $this->setActive();
        }
    
        return $this;
    }
    

    This would solve such a big headache, please, let us implement it. 😃

    opened by lukasoppermann 5
  • [Suggestion] Fluent API for considering authorization

    [Suggestion] Fluent API for considering authorization

    Originally posted by @themsaid here: https://github.com/spatie/menu/issues/1

    Menu::new()
        ->link('/', 'Home')
        ->linkIfCan('/products', 'Products', 'review_products');
        ->linkIfCan('/inventory', 'Inventory', ['check_inventory', 'update_inventory']);
    
    opened by sebastiandedeyne 5
  • Invalid Scheme using javascript:;

    Invalid Scheme using javascript:;

    For a dropdown menu I'm using a "javascript:;" as href in a parent item.

    Whenever I add a Link method with URL: javascript:; on a Link object:

    Link::to("javascript:;", "Demo), I get a Laravel Exception on the setActive() method:

    The scheme javascript isn't valid. It should be either http or https

    Spatie\Url\Exceptions\InvalidArgument::invalidScheme vendor/spatie/url/src/Exceptions/InvalidArgument.php:11

    Is there any way to resolve this matter without having to enter the <a href> via the HTML method?

    opened by i6media 4
  • Add getName and getData methods

    Add getName and getData methods

    It would be great if the name and data properties could be exposed.

    I've added methods, but maybe it should be:

    public function __construct(
            public string $name,
            public array $data = [],
        ) {
            $this->parentAttributes = new Attributes();
        }
    

    To give you an idea why it would be useful:

    public function getTab(): ?array
    {
            $this->tabs()->each(function (View $tab) {
                if ($tab->getName() === $this->activeTab) {
                     // do something
                 }
            });
    }
    

    Thanks!

    opened by francoism90 2
Releases(4.1.0)
Owner
Spatie
Webdesign agency based in Antwerp, Belgium
Spatie
Laravel Design Pattern Generator (api generator)

Laravel Design Pattern Generator (api generator) you can create your restful api easily by using this library and you can filter, sort and include elo

HusseinAlaa 2 Sep 25, 2022
Html-sanitizer - The HtmlSanitizer component provides an object-oriented API to sanitize untrusted HTML input for safe insertion into a document's DOM.

HtmlSanitizer Component The HtmlSanitizer component provides an object-oriented API to sanitize untrusted HTML input for safe insertion into a documen

Symfony 201 Dec 23, 2022
A TWBS menu builder for Laravel

Laravel Menu Builder A menu builder for Laravel 4-5 using Bootstrap's markup. Документация на Русском Note that this package is shipped with no styles

Alexander Kalnoy 24 Nov 29, 2022
📝 Artisan Menu - Use Artisan via an elegant console GUI

?? Artisan Menu Use Artisan via an elegant console GUI Features Run built-in and custom Artisan commands from a console GUI Prompts to enter required

Jordan Hall 149 Dec 29, 2022
Menu Library for PHP

KnpMenu The KnpMenu library provides object oriented menus for PHP. It is used by the KnpMenuBundle for Symfony but can now be used stand-alone. Insta

KNP Labs 1.3k Jan 1, 2023
MUP - Menu Up

MUP (aka: 'Menu Up') What is it? It's a bash script that generates a selection menu from a simple configuration file. Config: [Cache: Flush && Clean]

Nathan 9 Aug 19, 2020
📝 Artisan Menu - Use Artisan via an elegant console GUI

?? Artisan Menu Use Artisan via an elegant console GUI Features Run built-in and custom Artisan commands from a console GUI Prompts to enter required

Jordan Hall 148 Nov 29, 2022
This tool gives you the ability to set the default collapse state for Nova 4.0 menu items.

Nova Menu Collapsed This tool gives you the ability to set the default collapse state for Nova 4.0 menu items. Requirements php: >=8.0 laravel/nova: ^

Artem Stepanenko 10 Nov 17, 2022
Plugin for Filament Admin that adds a dropdown menu to the header to quickly create new items.

Filament Quick Create Plugin for Filament Admin that adds a dropdown menu to the header to quickly create new items from any page. Installation Instal

Adam Weston 45 Dec 27, 2022
A package that uses blade templates to control how markdown is converted to HTML inside Laravel, as well as providing support for markdown files to Laravel views.

Install Install via composer. $ composer require olliecodes/laravel-etched-blade Once installed you'll want to publish the config. $ php artisan vendo

Ollie Codes 19 Jul 5, 2021
Laravel HTMLMin - a simple HTML minifier for Laravel

Laravel HTMLMin Laravel HTMLMin is currently maintained by Raza Mehdi, and is a simple HTML minifier for Laravel. It utilises Mr Clay's Minify package

null 948 Mar 15, 2022
Specially customized Laravel jetstream's scaffolding for Frest html + laravel admin Template

frest-html-laravel-jetstream Specially customized Laravel jetstream's scaffolding for Frest html + laravel admin Template. It'll not work with any oth

PIXINVENT CREATIVE STUDIO 0 Apr 5, 2022
A Laravel and Lumen Badges Generator

Laravel and Lumen Badge Generator That package is a easy wrapper to Badges/Poser. #Installing composer require vluzrmos/laravel-badge-poser Laravel co

Vagner Luz do Carmo 6 Jun 10, 2020
A package for Laravel One Time Password (OTP) generator and validation without Eloquent Model, since it done by Cache.

Laravel OTP Introduction A package for Laravel One Time Password (OTP) generator and validation without Eloquent Model, since it done by Cache. The ca

Lim Teck Wei 52 Sep 6, 2022
Laravel Livewire (TALL-stack) form generator with realtime validation, file uploads, array fields, blade form input components and more.

TALL-stack form generator Laravel Livewire, Tailwind forms with auto-generated views. Support Contributions Features This is not an admin panel genera

TinaH 622 Jan 2, 2023
Promotional Codes Generator for Laravel >5

laravel-promocodes Promocodes generator for Laravel 5.*. Trying to make the best package in this category. You are welcome to join the party, give me

Zura Gabievi 425 Dec 26, 2022
A Laravel Code Generator based on your Models using Blade Template Engine

Laravel Code Generator is a PHP Laravel Package that uses Blade template engine to generate code for you. The difference between other code generators

Victor Yoalli 59 Dec 5, 2022
Laravel 5 Model Factory Generator

Laravel 5 Model Factory Generator This package offers a lazy way to create a new model factory files, since Laravel (< 5.5) have no Artisan command to

Roni Yusuf Manalu 16 Feb 15, 2020
API generator for Laravel 5

Apify API generator for Laravel 5 Table Of Contents Installation Configuration Usage Installation To install apify use composer Download composer requ

Erik C. Forés 26 Dec 14, 2022