vespakoen / menu
轻松管理菜单。
Requires
- php: >=5.4.0
- anahkiasen/html-object: ~1.4
- anahkiasen/underscore-php: ^2.0
- illuminate/config: 6.*|^7
- illuminate/container: 6.*|^7
- illuminate/http: 6.*|^7
Requires (Dev)
- orchestra/testbench: 3.0.*
- phpunit/phpunit: 4.0
README
你是那种喜欢在视图文件中手动编写菜单的人吗?或者你发现自己在寻找保存网站页面链接的最佳位置?那么,菜单(Menu)就是为你准备的!
快速概览示例
$menu = Menu::handler('mailbox'); // items $menu ->add('contacts', 'Contacts') ->add('inbox', 'Inbox') ->raw(null, null, ['class' => 'divider']) ->add('folders', 'Folders', Menu::items() ->prefixParents() ->add('urgent', 'Urgent') // with prefix: /folders/urgent ->add('sent', 'Sent') ->add('deleted', 'Deleted') ); // styling $menu ->addClass('nav navbar-nav') ->getItemsByContentType(Menu\Items\Contents\Link::class) ->map(function($item) { if ( $item->isActive() ) { $item->addClass('active'); } });
{!! $menu !!}
将输出
<ul class="nav navbar-nav"> <li class="active"> <!-- current element in laravel, detected by library --> <a href="http://myapp.com/contacts">Contacts</a> </li> <li> <a href="http://myapp.com/inbox">Inbox</a> </li> <li class="divider"></li> <li> <a href="http://myapp.com/folders">Folders</a> <ul> <li> <a href="http://myapp.com/folders/urgent">Urgent</a> </li> <li> <a href="http://myapp.com/folders/sent">Sent</a> </li> <li> <a href="http://myapp.com/folders/deleted">Deleted</a> </li> </ul> </li> </ul>
关键概念
项目列表
项目列表是菜单的核心,它应该很容易理解,因为它仅仅存储了一个项目列表。项目列表有一些可用的配置。例如,你可以设置用于渲染列表的 HTML 元素,在每个项目中添加所有父级 URL 段落作为前缀,等等。我们将在后面探讨这些选项。
菜单处理器
菜单处理器允许我们创建和交互项目列表,并且是存储和检索我们的菜单的地方。因为我们能够同时交互多个项目列表,所以我们有了一些有趣的选项。
项目
Menu 包箱提供了两种类型的项目。
- 链接 用于创建到其他页面的链接
- 原始 你可以在项目中添加任何你喜欢的。这种类型通常用于分隔符、标题等。
项目的 HTML 元素和属性也可以更改,我们将在后面讨论这个话题。
安装
Laravel 3
通过 artisan 命令行工具安装 Menu。打开终端,导航到你的 Laravel 项目的根目录。现在输入以下命令
php artisan bundle:install menu
为了让 Laravel 知道 Laravel Menu 包应该启动,打开 application/packages.php
并将以下行添加到 packages 数组中。
'menu' => array('auto' => true),
Laravel 4
将以下内容添加到你的 composer.json
文件中的 "require"
"vespakoen/menu": "2.*"
并将以下内容添加到你的 app/config/app.php
文件中
- 在 Service Providers 数组中:
'Menu\MenuServiceProvider',
- 在 aliases 数组中:
'Menu' => 'Menu\Menu',
Laravel 5
将以下内容添加到你的 composer.json
文件中的 "require"
"vespakoen/menu": "3.*"
将以下内容添加到你的 config/app.php
文件中
- 在 Service Providers 数组中:
'Menu\MenuServiceProvider',
- 在 aliases 数组中:
'Menu' => 'Menu\Menu',
最后,从你的项目根目录运行以下命令
php artisan vendor:publish
基本用法
首先,让我们将一些页面加载到菜单中。我们将通过利用 hydrate
方法来完成此操作。
Menu::handler('main')->hydrate(function() { return Page::with('translation') ->where('group', '=', 'main') ->get(); }, function($children, $item) { $children->add($item->translation->slug, $item->translation->name, Menu::items($item->as)); }); /* the hydrate method takes these arguments $resolver Closure A callback to resolve results $decorator Closure A callback that gets called for every result fetched from the resolver with the corresponding ItemList and result as the arguments $idField integer (default = 'id') the property on the result that contains the id $parentIdField integer (default = 'parent_id') the property on the result that contains the parent id $parentId integer (default = 0) the parentId to start hydrating from */
现在我们已经将页面加载到菜单中,甚至通过 Menu::items($item->as)
为每个菜单项识别了名称,我们有很多选项可供选择。
通过名称查找节点并添加子项。
Menu::find('users') ->add('users/create', 'Create new user');
为根节点添加一些属性
Menu::handler('main') ->addClass('nav navbar-nav');
获取一定深度处的所有 ItemList
并添加一个类
Menu::handler('main') ->getItemListsAtDepth(0) ->addClass('level-1');
获取深度范围的所有 ItemList
并更改元素
Menu::handler('main') ->getItemListsAtDepthRange(0,2) ->setElement('div');
获取一定深度处的所有 Item
并添加一个类
Menu::handler('main') ->getItemsAtDepth(0) ->addClass('level-1');
通过内容类型获取 Item
并使用 map 函数遍历结果,根据收集到的信息执行操作
Menu::handler('main') ->getItemsByContentType('Menu\Items\Contents\Link') ->map(function($item) { if($item->isActive() && $item->hasChildren()) { $item->addClass('is-active-link-with-children'); } if($item->getContent()->getUrl() == 'home') { $item->addClass('is-home'); } });
获取所有 ItemList
并如果它们有子项则添加一个类
Menu::handler('main') ->getAllItemLists() ->map(function($itemList) { if($itemList->hasChildren()) { $itemList->addClass('has-children'); } });
面包屑
面包屑地狱已成为过去。
准备好的 Bootstrap 面包屑就像这样简单
Menu::handler('main') ->breadcrumbs() ->setElement('ol') ->addClass('breadcrumb');
面包屑方法搜索所有处理程序并返回一个普通的ItemList,你可以对其进行操作。如果你直接在Menu类上调用面包屑方法,它将搜索所有你的处理程序中的面包屑,并且默认返回第一个匹配项。但是,可能有些情况下你想从找到的面包屑中选择,为此你可以将回调方法作为第一个参数提供。
以下是一个示例:
Menu::breadcrumbs(function($itemLists) { return $itemLists[0]; // returns first match }) ->setElement('ol') ->addClass('breadcrumb');
深入了解
Laravel Menu包包含几个类,但你可以通过Menu类与它们全部交互。让我们来看看handler方法。它只接受一个字符串或数组作为参数,给定的字符串是我们要检索的项目列表的名称。如果请求的项目列表还不存在,它将为我们创建它。在菜单类找到并创建了我们要的项目列表之后,它将返回一个处理这些项目列表的菜单处理程序。
// Get a MenuHandler instance that handles an ItemList named "main" Menu::handler('main');
当我们对这个菜单处理程序调用一个方法时,它将简单地转发调用到它所管理的所有项目列表。为了了解我们现在有了处理程序可以做什么,我们需要看看ItemList类上的方法。
ItemList类有一个名为add的方法,你可能经常使用它。它向ItemList添加一个类型为"link"的Item。
Menu::handler('main')->add('home', 'Homepage'); /* The add method takes these arguments $url string The URL to another page $title string The visible string on the link $children (default = null) ItemList (optional) The children of this page $link_attributes (default = array()) array (optional) HTML attributes for the <a> element $item_attributes (default = array()) array (optional) HTML attributes for the list element (usually <li>) $item_element (default = 'li') string (optional) The type of the list element */
让我们看看raw方法,用于向列表添加"任何内容"。
Menu::handler('main')->raw('<img src="img/seperator.gif">'); /* The raw method takes these arguments $html string The contents of the item $children (default = null) ItemList (optional) The children of this item $item_attributes (default = array()) array (optional) HTML attributes for the list element (usually <li>) $item_element (default = 'li') string (optional) The type of the list element */
太好了!现在我们知道了如何向项目列表添加项目,让我们看看如何向项目添加子项。每个项目都可以有子项,子项对象是另一个ItemList。正如我们之前看到的,我们可以通过handler方法创建项目列表,但这个方法返回一个MenuHandler,使其无法用于项目子项。那么我们该用什么呢?items方法返回一个新的ItemList对象。让我们看看。
Menu::handler('main') ->add('home', 'Homepage', Menu::items() ->add('sub-of-home', 'Sub of homepage')); /* The items method takes these arguments $name (default = null) string (optional) The name (=identifier) of this ItemList $attributes (default = array()) array (optional) HTML attributes for the ItemList element (usually <ul>) $element (default = 'ul') string (optional) The type of the ItemList element */
因此,现在我们知道如何构建菜单,添加项目和带有子项的项目。让我们看看如何显示菜单。MenuHandler和ItemList类实现了"__toString"方法,该方法调用render方法。这意味着你可以简单地echo MenuHandler或ItemList对象。以下是一个示例,以使事情更加清晰。
echo Menu::handler('main'); // Is the same as echo Menu::handler('main')->render();
现在我们已经掌握了基础知识,我们将探索这个包提供的其他一些酷炫特性。
类图
一些最后的话
感谢您跟随使用这个包。特别感谢@Anahkiasen重构了这个包并给它注入了新的活力!