Html menu generator

Related tags

CMS html php menus
Overview

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.

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

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 discover any security related issues, please email [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.

Comments
  • Add support for Bootstrap 4

    Add support for Bootstrap 4

    When merged this PR adds support for Bootstrap 4.

    We added 3 new methods for the Menu class:

    • setTagName enables using another element as an <ul>
    • setWrapLinksInList can disable automatic the wrapping of links in <li>'s
    • setActiveClassOnLink can set the activeClass on the link instead of the <li>

    To set the active class on the link we assume that the item supplied to renderItem implements HasHtmlAttributes. I think it is pretty safe to do so, but to be safe we added a check to see if the item implements HasHtmlAttributes.

    The syntax to render a Bootstrap 4 menu looks like this:

    $submenu = Menu::new()
        ->setTagName('div')
        ->addClass('dropdown-menu')
        ->setWrapLinksInList(false)
        ->setActiveClassOnLink(true)
        ->add(Link::to('/about', 'About')->addParentClass('nav-item')->addClass('dropdown-item'));
    
    Menu::new()
        ->addClass('navbar-nav')
        ->add(Link::to('/', 'Home')->addParentClass('nav-item')->addClass('nav-link'))
        ->submenu(Link::to('#', 'Dropdown link')->addClass('nav-link dropdown-toggle')->setAttribute('data-toggle', 'dropdown'), $submenu->addParentClass('nav-item dropdown'))
        ->setActive(function (Link $link) {
            return $link->url() === '/about';
        })->render();
    
    opened by mrk-j 8
  • Feature empty item support

    Feature empty item support

    Resolves #40

    I chose to call the helper method in Menu.php empty(). That can be confusing but I thought you'd like the lower case trend in your methods. If you want, I can change it to emptyItem().

    opened by markwalet 6
  • Add class to <li> with submenu

    Add class to
  • 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>
    
    enhancement help wanted 
    opened by weijinnx 6
  • Reordering through different manipulations

    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

    opened by bobmulder 5
  • Fixes #78 ItemClass from parent menu cascades into submenu wrapper

    Fixes #78 ItemClass from parent menu cascades into submenu wrapper

    When adding an "item class" on an instance of \Spatie\Menu\Menu via addItemClass(), it's possible for menus and links to have the "item class" applied. Since the \Spatie\Menu\Menu class also implements \Spatie\Menu\HasHtmlAttributes interface, all links as well as submenus get the applied class.

    opened by eoghanobrien 5
  • Submenu active header

    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?

    opened by ju5t 4
  • Renderer class - decoupled from Menu

    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:

    • #28
    • #39
    opened by Gummibeer 4
  • Active menu item is not hightliting

    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');
    }
    
    opened by Fakhrulzaki94 4
  • Absolute and Relative URLs

    Absolute and Relative URLs

    Under "Determining the Active Items with a URL" the docs state:

    Mixing absolute and relative url's isn't an issue either.

    However I am finding that not to be the case. I am working on a CodeIgniter 4 adaptation of this library and I am initializing the instance to what the framework knows as the current and base URLs. The problem is that choosing the absolute/relative path forces the implementor into using the same.

    This PR adds two tests which demonstrate the issue. I would be willing to dig into the source and try to find a fix, but want to make sure these failures are indeed "bugs" before putting work into it.

    Note: I worked on this in v2 locally but the issue is happening against master as well in my Github Actions for PHP 8.

    opened by MGatner 3
  • Update ActiveUrlChecker.php

    Update ActiveUrlChecker.php

    A parent menu entry of a submenu does not get marked as active properly. This is most likely due to a wrong argument order in ActiveUrlChecker.php line 42:

    ...
    // If this url starts with the url we're matching with, it's active.
            if ($matchPath === $itemPath || Str::startsWith($matchPath, $itemPath)) {
                return true;
            }
    ...
    

    should be

    ...
    // If this url starts with the url we're matching with, it's active.
            if ($matchPath === $itemPath || Str::startsWith($itemPath, $matchPath)) {
                return true;
            }
    ...
    
    opened by Kibadda 3
  • Menu::wrap wraps menu and link element in Menu::submenu

    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>
    
    
    opened by crazytinkas 3
Releases(3.0.1)
Owner
Spatie
We create open source, digital products and courses for the developer community
Spatie
A WordPress theme.json generator from a PHP array

ItalyStrap Theme Json Generator WordPress Theme Json Generator the OOP way This is a WIP project and still experimental. The idea is to generate a fil

null 19 Sep 15, 2022
TYPO3 CMS extension which checks used CSS selectors in HTML output of the current page and removes CSS declarations which are unused.

EXT:css_coverage TYPO3 CMS extension which checks used CSS selectors in HTML output of the current page and removes CSS declarations which are unused.

Armin Vieweg 3 Apr 8, 2022
A module allowing you to write your Processwire template using MJML and get a converted HTML output using MJML API.

PageMjmlToHtml A module allowing you to write your Processwire template using MJML and get a converted HTML output using MJML API. This is considered

Romain Cazier 7 Oct 5, 2022
A repo of a simple blogsite in PHP, HTML and CSS.

A repository of a simple and fully functional blogsite - The Memoire, in PHP, HTML and CSS. The index page of this site has a summary of all the autho

Baaba Dampare 7 Jun 11, 2022
Html menu generator for Laravel

Html Menu Generator for Laravel This is the Laravel version of our menu package adds some extras like convenience methods for generating URLs and macr

Spatie 813 Jan 4, 2023
Html menu generator

Html Menu Generator The spatie/menu package provides a fluent interface to build menus of any size in your php application. If you're building your ap

Spatie 657 Dec 30, 2022
For the super admin, replace WP Admin Bar My Sites menu with an All Sites menu.

Super Admin All Sites Menu Also available at https://wordpress.org/plugins/super-admin-all-sites-menu/ Use | Prerequisite | Install | Filters | Demo |

Per Søderlind 18 Dec 17, 2022
Menu ordering/management application demo, like Wordpress menu manager

Menu manager like Wordpress using Laravel and Nestable See demo at: http://laravel-menu-builder.gopagoda.com/admin/menu Tutorial coming up at: http://

Maksim Surguy 336 Nov 25, 2022
Laravel 5 nested category/menu generator

Laravel 5 Nestable Laravel Nestable to work with recursive logic. Category level there is no limit but this may vary depending on your server performa

Ahmet 217 Nov 15, 2022
InfyOm Laravel Generator - API, Scaffold, Tests, CRUD Laravel Generator

InfyOm Laravel Generator Generate Admin Panels CRUDs and APIs in Minutes with tons of other features and customizations with 3 different themes. Read

InfyOmLabs (InfyOm Technologies) 3.5k Jan 1, 2023
Laravel CRUD Generator This Generator package provides various generators like CRUD, API, Controller, Model, Migration, View for your painless development of your applications.

Laravel CRUD Generator This Generator package provides various generators like CRUD, API, Controller, Model, Migration, View for your painless develop

AppzCoder 1.3k Jan 2, 2023
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
One time password generator, validator, and qrcode generator that has no web dependencies (self-contained) in PHP

otp-thing One time password generator, validator, and qrcode generator that has no web dependencies (self-contained) in PHP Introduction This started

Daniel Krusky 25 Apr 29, 2022
This bundle provides new generator command line tools for doctrine generator.

GenBundle This bundle provides new generator command line tools for doctrine generator, extending SensioGeneratorBundle. php bin/console gen:generate:

Koldo Picaza 5 Sep 6, 2016
CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very usefull when you're sending emails.

CssToInlineStyles class Installation CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline style

Tijs Verkoyen 5.7k Dec 29, 2022
Html Minifier adalah paket simpel untuk minify output Html, Css style, dan Javascript sebelum dirender ke browser untuk aplikasi Laravel anda.

Laravel Html Minifier Adalah Paket simpel untuk minify HTML, Css Style, dan Javascript sebelum dirender ke browser untuk aplikasi Laravel anda. Alat i

:D 16 Aug 17, 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
php html parser,类似与PHP Simple HTML DOM Parser,但是比它快好几倍

HtmlParser php html解析工具,类似与PHP Simple HTML DOM Parser。 由于基于php模块dom,所以在解析html时的效率比 PHP Simple HTML DOM Parser 快好几倍。 注意:html代码必须是utf-8编码字符,如果不是请转成utf-8

俊杰jerry 522 Dec 29, 2022
html-sanitizer is a library aiming at handling, cleaning and sanitizing HTML sent by external users

html-sanitizer html-sanitizer is a library aiming at handling, cleaning and sanitizing HTML sent by external users (who you cannot trust), allowing yo

Titouan Galopin 381 Dec 12, 2022
Sanitize untrustworthy HTML user input (Symfony integration for https://github.com/tgalopin/html-sanitizer)

html-sanitizer is a library aiming at handling, cleaning and sanitizing HTML sent by external users (who you cannot trust), allowing you to store it and display it safely. It has sensible defaults to provide a great developer experience while still being entierely configurable.

Titouan Galopin 86 Oct 5, 2022