为 Laravel 应用快速生成 HTML 导航菜单的扩展包:Laravel Menu

几乎每个网站都有导航菜单,生成这些HTML导航菜单看似简单,但随着菜单数目的增加也会变得越来越麻烦:不仅仅是要渲染一些基本的HTML,更多时候往往还需要管理哪些菜单当前是激活的,如果某个菜单还有子菜单你还想要让被激活的子菜单的父级也是被激活的,更有甚者,有时候你还需要在一些菜单项之间插入HTML。

为此,我编写了一个扩展包(GitHub地址:https://github.com/spatie/laravel-menu),该扩展包提供的API简单优雅,并且有完整丰富的文档,这里我简单带着大家过一遍其使用方法。

尽管这个扩展包是独立于框架的,但这里我们设定在Laravel应用中使用它。

首先我们使用Composer安装这个扩展:

composer require spatie/laravel-menu

然后在config/app.phpprovidersaliases中注册服务提供者和门面:

// config/app.php

'providers' => [
    // ...
    Spatie\Menu\Laravel\MenuServiceProvider::class,
],

'aliases' => [
    // ...
    'Menu' => Spatie\Menu\Laravel\MenuFacade::class,
],

接下来我们在使用它生成HTML导航菜单。

假设我们要生成这样的菜单:

<ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
</ul>

这里是其实现代码:

$menu = Menu::new()
    ->add(Link::to('/', 'Home'))
    ->add(Link::to('/about', 'About'));

然后我们可以在视图中使用$menu->render()方法或者直接通过Menu对象上的__toString()方法显示菜单:

// in a blade view
Here is the menu: {!! $menu !!}

下面我们尝试生成更复杂的菜单:

<ul>
    <li>
        <ul>
            <li><a href="/introduction">Introduction</a></li>
            <li><a href="/requirements">Requirements</a></li>
            <li><a href="/installation-setup">Installation and Setup</a></li>
        </ul>
    </li>
    <li>
        <h2>Basic Usage</h2>
        <ul>
            <li><a href="/basic-usage/your-first-menu">Your First Menu</a></li>
            <li><a href="/basic-usage/working-with-items">Working With Items</a></li>
            <li><a href="/basic-usage/adding-sub-menus">Adding Sub Menus</a></li>
        </ul>
    </li>
</ul>

没错,这就是文档界面的导航菜单,注意到在每个二级子菜单前都有一个标题。对应的生成代码如下:

Menu::new()
    ->add(Menu::new()
        ->link('/introduction', 'Introduction')
        ->link('/requirements', 'Requirements')
        ->link('/installation-setup', 'Installation and Setup')
    )
    ->add(Menu::new()
        ->prepend('<h2>Basic Usage</h2>')
        ->prefixLinks('/basic-usage')
        ->link('/your-first-menu', 'Your First Menu')
        ->link('/working-with-items', 'Working With Items')
        ->link('/adding-sub-menus', 'Adding Sub Menus')
    );

如果你想要让某个菜单项被激活,可以调用setActive方法:

$menu = Menu::new()
    ->add(Link::to('/', 'Home'))
    ->add(Link::to('/about', 'About')->setActive());

手动设置菜单项激活是非常烦人的,在大多数案例中更合适的方式是让代码自己判断哪些菜单项被激活:

$menu = Menu::new()
    ->add(Link::to('/', 'Home'))
    ->add(Link::to('/about', 'About')->setActive());
    ->setActiveFromRequest();

除了指定链接之外你还可以灵活使用其它方法指向菜单项:

Menu::new()
    ->url('/', 'Home')
    ->route('contact', 'Contact')
    ->action('AcmeController@detail', 'Acme');

在这个扩展包中还有很多其它有用的方法,比如属性操作、追加内容、支持Macro等,完整文档请参考:https://docs.spatie.be/menu/v1/

声明:本文为译文,原文请看这里

学院君

学院君 has written 548 articles

资深PHP工程师,Laravel学院院长