mimmi20 / mezzio-navigation-laminasviewrenderer-bootstrap
为Mezzio导航提供Bootstrap视图助手
Requires
- php: ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0
- ext-mbstring: *
- laminas/laminas-view: ^2.35.0
- mimmi20/laminasviewrenderer-helper-htmlelement: ^2.0.8
- mimmi20/laminasviewrenderer-helper-partialrenderer: ^2.0.3
- mimmi20/mezzio-navigation: ^3.0.7
- mimmi20/mezzio-navigation-laminasviewrenderer: ^3.0.4
- mimmi20/navigation-helper-containerparser: ^4.0.4
- mimmi20/navigation-helper-htmlify: ^4.0.4
- psr/container: ^1.1.2 || ^2.0.2
- psr/log: ^3.0.0
Requires (Dev)
- ext-ctype: *
- ext-dom: *
- ext-intl: *
- ext-simplexml: *
- ext-tokenizer: *
- ext-xml: *
- ext-xmlreader: *
- ext-xmlwriter: *
- infection/infection: ^0.27.11 || ^0.28.1
- laminas/laminas-config: ^3.9.0
- laminas/laminas-escaper: ^2.13.0
- laminas/laminas-i18n: ^2.28.1
- laminas/laminas-permissions-acl: ^2.16.0
- laminas/laminas-servicemanager: ^3.22.1
- mezzio/mezzio-authentication: ^1.9.0
- mezzio/mezzio-helpers: ^5.16.0
- mezzio/mezzio-laminasviewrenderer: ^2.15.1
- mezzio/mezzio-router: ^3.17.0
- mimmi20/coding-standard: ^5.2.43
- mimmi20/mezzio-generic-authorization: ^3.0.6
- mimmi20/mezzio-generic-authorization-acl: ^3.0.4
- mimmi20/navigation-helper-acceptpage: ^2.1.4
- mimmi20/navigation-helper-converttopages: ^2.1.6
- mimmi20/navigation-helper-findactive: ^2.1.4
- mimmi20/navigation-helper-findfromproperty: ^2.1.5
- mimmi20/navigation-helper-findroot: ^2.1.4
- nikic/php-parser: ^4.19.1 || ^5.0.2
- phpstan/extension-installer: ^1.4.3
- phpstan/phpstan: ^1.12.3
- phpstan/phpstan-deprecation-rules: ^1.2.1
- phpstan/phpstan-phpunit: ^1.4.0
- phpunit/phpunit: ^10.5.25
- psr/http-server-middleware: ^1.0.2
- rector/rector: ^1.2.5
- rector/type-perfect: ^0.2.0
- symplify/phpstan-rules: ^13.0.1
- tomasvotruba/cognitive-complexity: ^0.2.3
- tomasvotruba/type-coverage: ^0.3.1
- tomasvotruba/unused-public: ^0.3.11
Suggests
- ext-intl: required to use the Translator
- laminas/laminas-config: ^3.5.0, to provide page configuration (optional, as arrays and Traversables are also allowed)
- laminas/laminas-i18n: ^2.11.0, required to use the Translator
- laminas/laminas-servicemanager: ^3.6.4, to use the navigation factories
- mimmi20/mezzio-generic-authorization: ^1.0.1, to use authrization roles or privileges
README
代码状态
安装
运行
composer require mimmi20/mezzio-navigation-laminasviewrenderer-bootstrap
渲染导航
在布局脚本中调用菜单视图助手
<!-- ... --> <body> <?= $this->navigation('default')->menu() ?> </body> <!-- ... -->
使用多个导航
一旦mezzio-navigation模块注册,您可以创建任意多的导航定义,底层的工厂将自动创建导航容器。
将容器定义添加到配置文件中,例如 config/autoload/global.php
<?php return [ // ... 'navigation' => [ // Navigation with name default 'default' => [ [ 'label' => 'Home', 'route' => 'home', ], [ 'label' => 'Page #1', 'route' => 'page-1', 'pages' => [ [ 'label' => 'Child #1', 'route' => 'page-1-child', ], ], ], [ 'label' => 'Page #2', 'route' => 'page-2', ], ], // Navigation with name special 'special' => [ [ 'label' => 'Special', 'route' => 'special', ], [ 'label' => 'Special Page #2', 'route' => 'special-2', ], ], // Navigation with name sitemap 'sitemap' => [ [ 'label' => 'Sitemap', 'route' => 'sitemap', ], [ 'label' => 'Sitemap Page #2', 'route' => 'sitemap-2', ], ], ], // ... ];
容器名称有前缀
在使用mezzio-navigation作为模块时,有一个重要的事项需要了解:在您的视图脚本中,容器的名称 必须 以
Mezzio\Navigation\
为前缀,后跟配置键的名称。这有助于确保不会与其他服务发生命名冲突。
以下示例演示了渲染名为 default
、special
和 sitemap
的容器中的导航菜单。
<!-- ... --> <body> <?= $this->navigation('Mimmi20\Mezzio\Navigation\Default')->menu() ?> <?= $this->navigation('Mimmi20\Mezzio\Navigation\Special')->menu() ?> <?= $this->navigation('Mimmi20\Mezzio\Navigation\Sitemap')->menu() ?> </body> <!-- ... -->
视图助手
导航助手用于从 Mimmi20\Mezzio\Navigation\Navigation
实例渲染导航元素,以便与Bootstrap一起使用。
有2个内置助手
- 面包屑,用于渲染当前活动页面的路径。
- 菜单,用于渲染菜单。
所有内置助手都实现了接口 Mimmi20\Mezzio\Navigation\LaminasView\View\Helper\Navigation\ViewHelperInterface
,这增加了与 laminas-acl 或 laminas-rbac 以及 laminas-i18n 的集成。
如果没有明确设置容器,助手将在调用 $helper->getContainer()
时创建一个空的 Mezzio\Navigation\Navigation
容器。
代理对导航容器的调用
导航视图助手使用魔法方法 __call()
将方法调用代理到在视图助手中注册的导航容器。
$this->navigation()->addPage([ 'type' => 'uri', 'label' => 'New page', ]);
上面的调用将在 Navigation
助手中添加一个页面到容器。
标签和标题的翻译
导航助手支持页面标签和标题的翻译。
如果代理助手没有翻译器,代理助手将向其代理的助手注入自己的翻译器。
权限集成
所有导航视图助手都支持权限。如果助手中使用了权限,助手中的角色必须被权限允许才能访问页面的 resource
和/或拥有页面的 privilege
以便在渲染时包含页面。
如果页面不被权限接受,任何子页面也将被排除在渲染之外。
如果代理助手没有权限,代理助手将向其代理的助手注入自己的权限和角色。
面包屑
面包屑用于指示用户当前在网站结构中的位置,通常渲染如下
You are here: Home > Products > FantasticProduct 1.0
《breadcrumbs()` 助手》遵循 Yahoo! 设计模式库中概述的面包屑模式,允许简单的自定义(最小/最大深度、缩进、分隔符以及是否将最后一个元素链接),或使用部分视图脚本进行渲染。
Breadcrumbs 助手在导航容器中找到最深层的活动页面,并渲染一个向上到根的路径。对于路由页面,页面的“活动性”是通过检查请求对象来确定的,如页面部分所述。
默认情况下,助手将 minDepth
属性设置为 1,这意味着如果最深层的活动页面是根页面,则不会渲染面包屑。如果指定了 maxDepth
,助手将在指定的深度停止渲染(例如,即使在最深层的活动页面在第三级,也会在第二级停止)。
基本用法
此示例显示了如何使用默认设置渲染面包屑。
在一个视图脚本或布局中
<?= $this->navigation()->breadcrumbs(); ?>
上面的调用利用了神奇的 __toString()
方法,等同于
<?= $this->navigation()->breadcrumbs()->render(); ?>
输出
<a href="/products">Products</a> > <a href="/products/server">Foo Server</a> > FAQ
指定缩进
此示例显示了如何渲染带有初始缩进的面包屑。
使用 8 个空格缩进渲染
<?= $this->navigation()->breadcrumbs()->setIndent(8) ?>
输出
<a href="/products">Products</a> > <a href="/products/server">Foo Server</a> > FAQ
自定义输出
此示例显示了如何通过指定多个选项来自定义面包屑输出。
在一个视图脚本或布局中
<?= $this->navigation()->breadcrumbs() ->setLinkLast(true) // link last page ->setMaxDepth(1) // stop at level 1 ->setSeparator(' ▶' . PHP_EOL); // cool separator with newline ?>
输出
<a href="/products">Products</a> ▶ <a href="/products/server">Foo Server</a>
设置渲染面包屑所需的最小深度
<?= $this->navigation()->breadcrumbs()->setMinDepth(10) ?>
输出:无,因为最深层的活动页面不在第 10 级或更深。
菜单
menu()
助手用于从导航容器中渲染菜单。默认情况下,菜单将使用 HTML UL
和 LI
标签进行渲染,但助手还允许使用部分视图脚本。
基本用法
此示例显示了如何从视图助手中注册/找到的容器中渲染菜单。注意,页面是基于可见性和 ACL 进行过滤的。
在一个视图脚本或布局中
<?= $this->navigation()->menu()->render() ?>
或者
<?= $this->navigation()->menu() ?>
输出
<ul class="navigation"> <li> <a title="Go Home" href="/">Home</a> </li> <li class="active"> <a href="/products">Products</a> <ul> <li class="active"> <a href="/products/server">Foo Server</a> <ul> <li class="active"> <a href="/products/server/faq">FAQ</a> </li> <li> <a href="/products/server/editions">Editions</a> </li> <li> <a href="/products/server/requirements">System Requirements</a> </li> </ul> </li> <li> <a href="/products/studio">Foo Studio</a> <ul> <li> <a href="/products/studio/customers">Customer Stories</a> </li> <li> <a href="/products/studio/support">Support</a> </li> </ul> </li> </ul> </li> <li> <a title="About us" href="/company/about">Company</a> <ul> <li> <a href="/company/about/investors">Investor Relations</a> </li> <li> <a class="rss" href="/company/news">News</a> <ul> <li> <a href="/company/news/press">Press Releases</a> </li> <li> <a href="/archive">Archive</a> </li> </ul> </li> </ul> </li> <li> <a href="/community">Community</a> <ul> <li> <a href="/community/account">My Account</a> </li> <li> <a class="external" href="http://forums.example.com/">Forums</a> </li> </ul> </li> </ul>
直接调用 renderMenu()
此示例显示了如何通过直接调用 renderMenu()
并指定选项来渲染未在视图助手中注册的菜单。
<?php // render only the 'Community' menu $community = $this->navigation()->findOneByLabel('Community'); $options = [ 'indent' => 16, 'ulClass' => 'community' ]; echo $this->navigation() ->menu() ->renderMenu($community, $options); ?>
输出
<ul class="community"> <li> <a href="/community/account">My Account</a> </li> <li> <a class="external" href="http://forums.example.com/">Forums</a> </li> </ul>
渲染最深层的活动菜单
此示例显示了 renderSubMenu()
将如何渲染活动分支的最深子菜单。
调用 renderSubMenu($container, $ulClass, $indent)
等同于调用 renderMenu($container, $options)
并使用以下选项
[ 'ulClass' => $ulClass, 'indent' => $indent, 'minDepth' => null, 'maxDepth' => null, 'onlyActiveBranch' => true, 'renderParents' => false, ]
renderSubMenu
方法的使用
<?= $this->navigation() ->menu() ->renderSubMenu(null, 'sidebar', 4) ?>
如果 'FAQ' 或 'Foo Server' 是活动的,则输出将相同
<ul class="sidebar"> <li class="active"> <a href="/products/server/faq">FAQ</a> </li> <li> <a href="/products/server/editions">Editions</a> </li> <li> <a href="/products/server/requirements">System Requirements</a> </li> </ul>
使用最大深度渲染
<?= $this->navigation() ->menu() ->setMaxDepth(1) ?>
输出
<ul class="navigation"> <li> <a title="Go Home" href="/">Home</a> </li> <li class="active"> <a href="/products">Products</a> <ul> <li class="active"> <a href="/products/server">Foo Server</a> </li> <li> <a href="/products/studio">Foo Studio</a> </li> </ul> </li> <li> <a title="About us" href="/company/about">Company</a> <ul> <li> <a href="/company/about/investors">Investor Relations</a> </li> <li> <a class="rss" href="/company/news">News</a> </li> </ul> </li> <li> <a href="/community">Community</a> <ul> <li> <a href="/community/account">My Account</a> </li> <li> <a class="external" href="http://forums.example.com/">Forums</a> </li> </ul> </li> </ul>
使用最小深度渲染
<?= $this->navigation() ->menu() ->setMinDepth(1) ?>
输出
<ul class="navigation"> <li class="active"> <a href="/products/server">Foo Server</a> <ul> <li class="active"> <a href="/products/server/faq">FAQ</a> </li> <li> <a href="/products/server/editions">Editions</a> </li> <li> <a href="/products/server/requirements">System Requirements</a> </li> </ul> </li> <li> <a href="/products/studio">Foo Studio</a> <ul> <li> <a href="/products/studio/customers">Customer Stories</a> </li> <li> <a href="/products/studio/support">Support</a> </li> </ul> </li> <li> <a href="/company/about/investors">Investor Relations</a> </li> <li> <a class="rss" href="/company/news">News</a> <ul> <li> <a href="/company/news/press">Press Releases</a> </li> <li> <a href="/archive">Archive</a> </li> </ul> </li> <li> <a href="/community/account">My Account</a> </li> <li> <a class="external" href="http://forums.example.com/">Forums</a> </li> </ul>
仅渲染活动分支
<?= $this->navigation() ->menu() ->setOnlyActiveBranch(true) ?>
输出
<ul class="navigation"> <li class="active"> <a href="/products">Products</a> <ul> <li class="active"> <a href="/products/server">Foo Server</a> <ul> <li class="active"> <a href="/products/server/faq">FAQ</a> </li> <li> <a href="/products/server/editions">Editions</a> </li> <li> <a href="/products/server/requirements">System Requirements</a> </li> </ul> </li> </ul> </li> </ul>
仅渲染活动分支的最小深度
<?= $this->navigation() ->menu() ->setOnlyActiveBranch(true) ->setMinDepth(1) ?>
输出
<ul class="navigation"> <li class="active"> <a href="/products/server">Foo Server</a> <ul> <li class="active"> <a href="/products/server/faq">FAQ</a> </li> <li> <a href="/products/server/editions">Editions</a> </li> <li> <a href="/products/server/requirements">System Requirements</a> </li> </ul> </li> </ul>
仅渲染活动分支的最大深度
<?= $this->navigation() ->menu() ->setOnlyActiveBranch(true) ->setMaxDepth(1) ?>
输出
<ul class="navigation"> <li class="active"> <a href="/products">Products</a> <ul> <li class="active"> <a href="/products/server">Foo Server</a> </li> <li> <a href="/products/studio">Foo Studio</a> </li> </ul> </li> </ul>
仅渲染活动分支的最大深度且不显示父级
<?= $this->navigation() ->menu() ->setOnlyActiveBranch(true) ->setRenderParents(false) ->setMaxDepth(1) ?>
输出
<ul class="navigation"> <li class="active"> <a href="/products/server">Foo Server</a> </li> <li> <a href="/products/studio">Foo Studio</a> </li> </ul>
使用部分视图脚本渲染自定义菜单
此示例显示了如何使用部分视图脚本渲染自定义菜单。通过调用 setPartial()
,您可以在调用 render()
时指定一个部分视图脚本,当指定部分时,该方法将代理到 renderPartial()
方法。
renderPartial()
方法将容器分配给视图的 container
键。
在布局中
$this->navigation()->menu()->setPartial('my-module/partials/menu'); echo $this->navigation()->menu()->render();
在 module/MyModule/view/my-module/partials/menu.phtml
foreach ($this->container as $page) { echo $this->navigation()->menu()->htmlify($page) . PHP_EOL; }
输出
<a title="Go Home" href="/">Home</a> <a href="/products">Products</a> <a title="About us" href="/company/about">Company</a> <a href="/community">Community</a>
在部分视图脚本中使用额外的参数
从版本 2.6.0 开始,您可以将自定义变量分配给部分脚本。
在布局中
// Set partial $this->navigation()->menu()->setPartial('my-module/partials/menu'); // Output menu echo $this->navigation()->menu()->renderPartialWithParams( [ 'headline' => 'Links', ] );
在 module/MyModule/view/my-module/partials/menu.phtml
<h1><?= $headline ?></h1> <?php foreach ($this->container as $page) { echo $this->navigation()->menu()->htmlify($page) . PHP_EOL; } ?>
输出
<h1>Links</h1> <a title="Go Home" href="/">Home</a> <a href="/products">Products</a> <a title="About us" href="/company/about">Company</a> <a href="/community">Community</a>
在部分视图脚本中使用菜单选项
在布局中
// Set options $this->navigation()->menu() ->setUlClass('my-nav') ->setPartial('my-module/partials/menu'); // Output menu echo $this->navigation()->menu()->render();
在 module/MyModule/view/my-module/partials/menu.phtml
<div class"<?= $this->navigation()->menu()->getUlClass() ?>"> <?php foreach ($this->container as $page) { echo $this->navigation()->menu()->htmlify($page) . PHP_EOL; } ?> </div>
输出
<div class="my-nav"> <a title="Go Home" href="/">Home</a> <a href="/products">Products</a> <a title="About us" href="/company/about">Company</a> <a href="/community">Community</a> </div>
在部分视图脚本中使用权限
如果您想在部分视图脚本中使用权限,那么您将不得不手动检查对页面的访问权限。
在 module/MyModule/view/my-module/partials/menu.phtml
foreach ($this->container as $page) { if ($this->navigation()->accept($page)) { echo $this->navigation()->menu()->htmlify($page) . PHP_EOL; } }
默认使用 UTF-8 编码
默认情况下,laminas-view 使用 UTF-8 作为其默认编码。如果您想在
Sitemap
中使用其他编码,您需要做三件事
- 创建一个自定义渲染器并实现
getEncoding()
方法。- 创建一个自定义渲染策略,该策略将返回你的自定义渲染器的实例。
- 在
ViewEvent
中附加自定义策略。查看HeadStyle文档中的示例,了解如何实现此功能。
许可证
本软件包使用MIT许可证授权。
请参阅LICENSE.md
。