hieu-le/laravel-menu

帮助在 Laravel 应用程序中更轻松地构建菜单

1.0.2 2015-11-17 01:30 UTC

This package is auto-updated.

Last update: 2024-09-05 19:55:17 UTC


README

帮助在 Laravel 应用程序中更轻松地构建菜单(目前仅支持 Laravel 5)

Build Status Latest Stable Version Code Climate Test Coverage Total Downloads License

安装

首先,将此包添加到项目依赖中

$> composer require "hieu-le/laravel-menu"

在 Composer 更新您的 vendors 代码后,将包服务提供者添加到 config/app.php 文件中的 providers 数组

HieuLe\LaravelMenu\LaravelMenuServiceProvider::class,

现在,您可以通过 app('menu.manager') 对象访问菜单管理器。如果您想通过别名类使用静态方法,请将包外观注册到 config/app.php 文件中的 aliases 数组

'Menu' => HieuLe\LaravelMenu\Facades\LaravelMenu::class,

用法

您可以在应用程序中创建任意数量的菜单。每个菜单都有一个独特的名称,可以是任何东西。您可以通过 menu 方法通过该名称获取菜单实例

<?php
$menu = app('menu.manager')->menu($menuName); // the default value of $menuName is "default"

# with the registered alias, you can also do this
$menu = Menu::menu($menuName);
?>

如果没有您指定的名称的菜单,将创建一个新的并返回给您。一些菜单带有可选的 header(或 label),可以通过 setLabel 方法在 菜单实例 上设置。

<?php
$menu->setLabel('Sidebar navigation');
?>

此方法返回菜单实例本身以启用 方法链。许多菜单可以具有相同的标签或没有标签。请记住,您不能通过标签从菜单管理器检索菜单,您只能使用其 名称

我建议在两个地方定义您的菜单

  • 路由中间件
  • 服务提供者

添加链接到菜单

API: $menu->addLink($text, array $url = [], $options = [])

  • $text 是锚文本
  • $url 是一个 关联 数组,用于生成链接的 href 属性。更多详细信息将在后面解释。
  • $option 数组将在后面描述。

如果 $url 是一个空数组,则 href 将是一个哈希字符(#)。

要将 URL 分配给链接,请将字符串传递给 $url 数组的 to 元素。例如:使用 $url 等于 ['to' => '/foo/bar'] 创建的项目具有指向 http://your-domain.com/foo/barhref,使用 $url 等于 ['to' => 'http://other-site.com/foo/bar'] 创建的项目具有指向 http://other-site.com/foo/barhref

要通过命名的路由分配内部 URL,请将路由名称作为字符串传递给 $url 数组的 route 元素。如果该路由有参数,请传递一个数组,其中第一个元素是路由名称,其余是路由参数 以及适当的参数名称作为键。例如

<?php
// routes.php
Route::get('/posts/{post_id}/comments/{comment_id}', ['as' => 'posts.comments.detail'];

// your menu definitions
$menu->addLink($text, ['route' => ['posts.comments.detail', 'post_id' => 1, 'comment_id' => 99]]);

// the output link is: /posts/1/comments/99
?>

要通过操作名称分配内部 URL,请将操作作为字符串传递给 $url 数组的 action 元素。如果操作有参数,请传递一个数组,其中第一个元素是操作,其余是操作参数。例如

<?php
// routes.php
Route::get('/posts/{post_id}/comments/{comment_id}', ['use' => 'PostController@viewComment'];

// your menu definitions
$menu->addLink($text, ['action' => ['App\Http\Controllers\PostController@viewComment', 1, 99]]);

// the output link is: /posts/1/comments/99
?>

如果您的链接包含查询字符串,您可以将数组传递给 $url 数组的 query 元素。我使用 http_build_query 创建查询字符串并将其附加到上述选项创建的 URL 的末尾。

添加子菜单

API $menu->addSubMenu($menu, $options = [])

  • $menu 是一个菜单实例。您可以使用 Menu::menu($name) 创建一个可重复使用的子菜单,名称如上所述。还有另一种创建不带名称的菜单实例的方法:Menu::createMenu($label = '')。您可以使用此包创建嵌套菜单系统。
  • $options 数组与 addLink 函数相同。这个数组将在下一节中详细讨论。

创建新菜单项时的选项。

在创建新的菜单项(链接或子菜单)时,您可以传递一个可选的数组作为 $options 参数。该数组可以包含以下元素

  • before:链接内容之前的文本
  • after:链接内容之后的文本
  • is_active:检测此链接当前是否激活的函数。如果它缺失,我会通过使用我的 Laravel Active 包在地下为您完成。
  • id:项目的本地 ID。
  • next_to:您想要新菜单项插入 之后 的项目的本地 ID。如果本地 ID 在父菜单中找不到,则忽略,并将新项目正常附加到父菜单链接的末尾。
  • url_def:URL 定义,它与经理的 isActive 方法一起使用,以确定当前项是否为活动项。

渲染菜单

我使用 Laravel 内置的视图系统来渲染菜单,这样您就可以轻松地自定义菜单的输出。要获取菜单的 HTML,请从 菜单实例 调用 render 方法。

API:$menu->render($data = [], $view = '')

  • $data:传递给视图的额外数据
  • $view:要渲染的视图名称,它可以包含其他视图,就像正常的 Laravel 视图一样。如果为空,则使用默认值:menu_manager::master_menu

如果您使用默认的内置视图($view 参数为空),则 $data 数组中有 3 个元素,所有这些都是字符串

  • class:包裹整个菜单的外部最外层 UL 元素的附加类
  • childClass:包含子菜单的 LI 元素的附加类
  • childUlClass:包裹 子菜单 的 UL 元素的附加类,该元素位于一个应用了上述 childClass 类的 LI 元素内部。

检测当前菜单项是否为活动项

在视图中,您通常会想要向当前选中的菜单项添加一些 活动 类。此包提供了菜单管理器的 isActive 方法来完成此操作。您提供一个菜单项并获取一个布尔值,该值告诉您此菜单项当前是否为活动项。

<?php
foreach($menu->getItems() as $menuItem) {
    $class = Menu::isActive($menuItem) ? "active" : "";
    echo "<li class='{$class}'></li>
}
?>

isActive 方法首先检查当前菜单项的 is_active 元素,如果它是可调用的,则方法将返回该结果给您。

如果没有 is_active 元素,则方法使用上述 url_def 元素。该 url_def 元素描述可以使当前菜单项变为活动的 URL。其值是一个关联数组

  • route:活动菜单项 URL 的路由名称
  • route_param:活动菜单项的路由参数
  • route_pattern:活动菜单项路由名称的模式
  • action:活动菜单项的动作
  • uri:活动菜单项的 URI
  • uri_pattern:活动菜单项 URI 的模式
  • query:活动菜单项的查询字符串变量

请参阅 Laravel Active 包的文档以获取更多详细信息。

默认视图的示例

// routes.php
Route::get('/a', ['as' => 'links.a']);
Route::get('/a/new', ['as' => 'links.a.create']);
Route::get('/a/list', ['as' => 'links.a.list']);
Route::get('/a/{id}', ['as' => 'links.a.detail']);
Route::get('/b', ['as' => 'links.b']);
Route::get('/c', ['as' => 'links.c']);


// AppServiceProvider.php
public function boot() {
    $subMenu = app('menu.manager')->createMenu('Multilevel link A')
        ->addLink('Create A', ['route' => 'links.a.create'])
        ->addLink('Listing A', ['route' => ['links.a.list']]);

    $menu = app('menu.manager')->menu('sidebar')
        ->setLabel('Sidebar Navigation')
        ->addSubMenu($subMenu, ['id' => 'link-a', 'url_def' => ['route_pattern' => 'link.a.*']])
        ->addLink('Link C', ['route' => 'links.c']);
        
    // some thing else ...
    
    app('menu.manager')->menu('sidebar')
        // we want to insert link B before link C
        ->addLink('Link B', ['route' => 'links.b'], 'next_to' => 'link-a']);
}

// Some where in your view
{!! app('menu.manager')->menu('sidebar')->render() !!}

如果您正在访问 URI /a/new,则输出的 HTML 将是

<ul class="menu">
    <li class="header">
        Sidebar Navigation
    </li>
    <li class="menuitem active">
        <a href="#">
            Multilevel link A
        </a>
        <ul class="menu submenu">
            <li class="menuitem item">
                <a href="/a/new">Create A</a>
            </li>
            <li class="menuitem item">
                <a href="/a/list">Listing A</a>
            </li>
        </ul>
    </li>
    <li class="menuitem item">
        <a href="/b">Link B</a>
    </li>
    <li class="menuitem item">
        <a href="/c">Link C</a>
    </li>
</ul>