mimmi20 / mezzio-navigation-laminasviewrenderer
为Mezzio导航提供视图助手
Requires
- php: ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0
- ext-mbstring: *
- laminas/laminas-stdlib: ^3.19.0
- laminas/laminas-view: ^2.35.0
- mezzio/mezzio-helpers: ^5.16.0
- mezzio/mezzio-laminasviewrenderer: ^2.15.1
- mimmi20/laminasviewrenderer-helper-partialrenderer: ^2.0.3
- mimmi20/mezzio-navigation: ^3.0.7
- mimmi20/navigation-helper-acceptpage: ^2.1.4
- mimmi20/navigation-helper-containerparser: ^4.0.4
- mimmi20/navigation-helper-findactive: ^2.1.4
- mimmi20/navigation-helper-findfromproperty: ^2.1.5
- mimmi20/navigation-helper-findroot: ^2.1.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-libxml: *
- 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-i18n: ^2.28.1
- laminas/laminas-json: ^3.6.0
- laminas/laminas-permissions-acl: ^2.16.0
- laminas/laminas-servicemanager: ^3.22.1
- laminas/laminas-uri: ^2.12.0
- laminas/laminas-validator: ^2.64.1
- mezzio/mezzio-authentication: ^1.9.0
- mezzio/mezzio-router: ^3.17.0
- mimmi20/coding-standard: ^5.2.43
- mimmi20/laminasviewrenderer-helper-htmlelement: ^2.0.8
- mimmi20/mezzio-generic-authorization: ^3.0.6
- mimmi20/mezzio-generic-authorization-acl: ^3.0.4
- mimmi20/navigation-helper-converttopages: ^2.1.6
- 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-message: ^2.0.0
- psr/http-server-middleware: ^1.0
- 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-dom: required to use the Sitemap ViewHelper
- ext-intl: required to use the Translator
- ext-libxml: required to use the Sitemap ViewHelper
- 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
- laminas/laminas-uri: ^2.7.1 || ^2.8.0, required to use the Sitemap ViewHelper
- laminas/laminas-validator: ^2.13.5 || ^2.14.0, required to use the Sitemap ViewHelper
- mimmi20/mezzio-generic-authorization: ^1.0.1, to use authrization roles or privileges
Conflicts
This package is auto-updated.
Last update: 2024-09-20 06:09:33 UTC
README
代码状态
安装
运行
composer require mimmi20/mezzio-navigation-laminasviewrenderer
渲染导航
在布局脚本中调用菜单视图助手
<!-- ... --> <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\Navigation\Special')->menu() ?> <?= $this->navigation('Mimmi20\Navigation\Sitemap')->menu() ?> </body> <!-- ... -->
视图助手
导航助手用于从Mimmi20\Mezzio\Navigation\Navigation
实例渲染导航元素。
有5个内置助手
- 面包屑,用于渲染当前活动页面的路径。
- 链接,用于渲染导航头部链接(例如
<link rel="next" href="..." />
)。 - 菜单,用于渲染菜单。
- 站点地图,用于渲染符合Sitemaps XML格式的站点地图。
- 导航,用于代理对其他导航助手的调用。
所有内置助手都实现了接口Mezzio\Navigation\LaminasView\View\Helper\Navigation\ViewHelperInterface
,它增加了与laminas-acl或laminas-rbac以及laminas-i18n的集成。该接口Mimmi20\Mezzio\Navigation\Helper\Navigation\HelperInterface
定义了以下方法
除了接口中的方法存根之外,抽象类还实现了以下方法
如果没有显式设置容器,助手将在调用$helper->getContainer()
时创建一个空的Mimmi20\Mezzio\Navigation\Navigation
容器。
代理对导航容器的调用
导航视图助手使用魔法方法__call()
将方法调用代理到在视图助手中注册的导航容器。
$this->navigation()->addPage([ 'type' => 'uri', 'label' => 'New page', ]);
上面的调用将在Navigation
助手中的容器中添加一个页面。
标签和标题的翻译
导航助手支持页面标签和标题的翻译。您可以在助手中使用$helper->setTranslator($translator)
设置类型为Laminas\I18n\Translator\TranslatorInterface
的翻译器。
如果您想禁用翻译,请使用$helper->setTranslatorEnabled(false)
。
代理助手将向它代理的助手中注入它自己的翻译器,如果代理助手尚未具有翻译器。
站点地图不使用翻译
由于XML站点地图中不涉及页面标签或标题,因此站点地图助手中没有翻译。
与ACL集成
所有导航视图助手都支持访问控制列表(ACL)。任何实现 Laminas\Permissions\Acl\AclInterface
接口的对象都可以通过 $helper->setAcl($acl)
分配给助手实例,并通过 $helper->setRole('member')
或 $helper->setRole(new Laminas\Permissions\Acl\Role\GenericRole('member'))
设置角色。如果助手中使用了ACL,则助手中的角色必须被ACL允许访问页面上的 resource
和/或具有页面的 privilege
,以便在渲染时包含该页面。
如果页面不被ACL接受,任何子页面也将被排除在渲染之外。
下面的 代理助手 将将其自己的ACL和角色注入它代理的助手,如果代理助手尚未设置任何内容。
下面的示例都显示了ACL如何影响渲染。
示例中使用的导航设置
本例展示了为一家虚构的软件公司设置导航容器的示例。
关于设置的说明
- 网站的域是
www.example.com
。 - 有趣的页面属性以注释标记。
- 除非在其他示例中另有说明,用户请求的是URL
http://www.example.com/products/server/faq/
,这对应于“Foo Server”下的FAQ
标签页。 - 以下是在容器设置下方显示的假设的ACL和路由设置。
use Mimmi20\Mezzio\Navigation\Navigation; /* * Navigation container * Each element in the array will be passed to * Mimmi20\Mezzio\Navigation\Page\(new PageFactory())->factory() when constructing * the navigation container below. */ $pages = [ [ 'label' => 'Home', 'title' => 'Go Home', 'module' => 'default', 'controller' => 'index', 'action' => 'index', 'order' => -100, // make sure home is the first page ], [ 'label' => 'Special offer this week only!', 'module' => 'store', 'controller' => 'offer', 'action' => 'amazing', 'visible' => false, // not visible ], [ 'label' => 'Products', 'module' => 'products', 'controller' => 'index', 'action' => 'index', 'pages' => [ [ 'label' => 'Foo Server', 'module' => 'products', 'controller' => 'server', 'action' => 'index', 'pages' => [ [ 'label' => 'FAQ', 'module' => 'products', 'controller' => 'server', 'action' => 'faq', 'rel' => [ 'canonical' => 'http://www.example.com/?page=faq', 'alternate' => [ 'module' => 'products', 'controller' => 'server', 'action' => 'faq', 'params' => ['format' => 'xml'], ], ], ], [ 'label' => 'Editions', 'module' => 'products', 'controller' => 'server', 'action' => 'editions', ], [ 'label' => 'System Requirements', 'module' => 'products', 'controller' => 'server', 'action' => 'requirements', ], ], ], [ 'label' => 'Foo Studio', 'module' => 'products', 'controller' => 'studio', 'action' => 'index', 'pages' => [ [ 'label' => 'Customer Stories', 'module' => 'products', 'controller' => 'studio', 'action' => 'customers', ], [ 'label' => 'Support', 'module' => 'products', 'controller' => 'studio', 'action' => 'support', ], ], ], ], ], [ 'label' => 'Company', 'title' => 'About us', 'module' => 'company', 'controller' => 'about', 'action' => 'index', 'pages' => [ [ 'label' => 'Investor Relations', 'module' => 'company', 'controller' => 'about', 'action' => 'investors', ], [ 'label' => 'News', 'class' => 'rss', // class 'module' => 'company', 'controller' => 'news', 'action' => 'index', 'pages' => [ [ 'label' => 'Press Releases', 'module' => 'company', 'controller' => 'news', 'action' => 'press', ], [ 'label' => 'Archive', 'route' => 'archive', // route 'module' => 'company', 'controller' => 'news', 'action' => 'archive', ], ], ], ], ], [ 'label' => 'Community', 'module' => 'community', 'controller' => 'index', 'action' => 'index', 'pages' => [ [ 'label' => 'My Account', 'module' => 'community', 'controller' => 'account', 'action' => 'index', 'resource' => 'mvc:community.account', // resource ], [ 'label' => 'Forums', 'uri' => 'http://forums.example.com/', 'class' => 'external', // class, ], ], ], [ 'label' => 'Administration', 'module' => 'admin', 'controller' => 'index', 'action' => 'index', 'resource' => 'mvc:admin', // resource 'pages' => [ [ 'label' => 'Write new article', 'module' => 'admin', 'controller' => 'post', 'action' => 'write', ], ], ], ]; // Create container from array $container = new Navigation(); $container->addPages($pages); // Store the container in the proxy helper: $view->plugin('navigation')->setContainer($container); // ...or simply: $view->navigation($container);
除了上面的容器外,还向模块的配置文件中添加了以下路由设置,例如 module/MyModule/config/module.config.php
return [ /* ... */ 'router' [ 'routes' => [ 'archive' => [ 'type' => 'Segment', 'options' => [ 'route' => '/archive/:year', 'defaults' => [ 'module' => 'company', 'controller' => 'news', 'action' => 'archive', 'year' => (int) date('Y') - 1, ], 'constraints' => [ 'year' => '\d+', ], ], ], /* You can have other routes here... */ ], ], /* ... */ ];
ACL的设置可以在模块类中完成,例如 module/MyModule/Module.php
namespace MyModule; use Laminas\View\HelperPluginManager as ViewHelperPluginManager; use Laminas\Permissions\Acl\Acl; use Laminas\Permissions\Acl\Role\GenericRole; use Laminas\Permissions\Acl\Resource\GenericResource; class Module { /* ... */ public function getViewHelperConfig() { return [ 'factories' => [ // This will overwrite the native navigation helper 'navigation' => function(ViewHelperPluginManager $pm) { // Setup ACL: $acl = new Acl(); $acl->addRole(new GenericRole('member')); $acl->addRole(new GenericRole('admin')); $acl->addResource(new GenericResource('mvc:admin')); $acl->addResource(new GenericResource('mvc:community.account')); $acl->allow('member', 'mvc:community.account'); $acl->allow('admin', null); // Get an instance of the proxy helper $navigation = $pm->get('Mezzio\Navigation\Helper\Navigation'); // Store ACL and role in the proxy helper: $navigation->setAcl($acl); $navigation->setRole('member'); // Return the new navigation helper instance return $navigation; } ] ]; } /* ... */ }
导航代理
navigation()
助手是一个代理助手,它将调用传递给其他导航助手。它可以被认为是所有导航相关视图任务的入口点。
Navigation
助手查找实现 Mezzio\Navigation\Helper\Navigation\HelperInterface
的其他助手,这意味着自定义视图助手也可以被代理。然而,这需要将自定义助手路径添加到视图中。
在代理到其他助手时,Navigation
助手可以注入其容器、ACL和可选的角色以及翻译器。这意味着您不必在所有导航助手中明确设置这三个元素,也不必通过静态方法注入。
方法
面包屑
面包屑用于指示用户当前在网站结构中的位置,通常像以下这样渲染:
You are here: Home > Products > FantasticProduct 1.0
breadcrumbs()
助手遵循Yahoo!设计模式库中概述的 面包屑模式,并允许简单的自定义(最小/最大深度、缩进、分隔符以及是否将最后一个元素链接),或使用部分视图脚本进行渲染。
面包屑助手找到导航容器中最深的活跃页面,并渲染到根的向上路径。对于页面,页面的“活跃性”通过检查请求对象来确定,如页面部分所述。
助手默认将 minDepth
属性设置为1,这意味着如果最深的活跃页面是根页面,则不会渲染面包屑。如果指定了 maxDepth
,则助手将在达到指定深度时停止渲染(例如,即使在最深的活跃页面在第3级,也将在第2级停止)。
面包屑助手中的方法
基本用法
此示例显示了如何使用默认设置渲染面包屑。
在视图脚本或布局中
<?= $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级或更深处。
使用部分视图脚本进行渲染
此示例展示了如何使用部分视图脚本渲染自定义的面包屑。通过调用setPartial()
,您可以为调用render()
时使用指定部分视图脚本来指定部分视图脚本。当指定了部分视图时,在生成面包屑时会调用renderPartial()
方法。此方法将找到最深的活跃页面,并将指向活跃页面的页面数组传递给部分视图脚本。
在布局中
echo $this->navigation()->breadcrumbs() ->setPartial('my-module/partials/breadcrumbs');
module/MyModule/view/my-module/partials/breadcrumbs.phtml
的内容
<?= implode(', ', array_map(function ($a) { return $a->getLabel(); }, $this->pages)); ?>
输出
Products, Foo Server, FAQ
链接
使用links()
辅助函数来渲染HTML LINK
元素。链接用于描述当前活跃页面的文档关系。更多关于链接和链接类型的信息,请参阅
存在两种关系类型;正向和反向,分别由关键词rel
和rev
表示。辅助函数中的大多数方法将接受一个$rel
参数,该参数必须是rel
或rev
。大多数方法还接受一个$type
参数,该参数用于指定链接类型(例如,alternate
、start
、next
、prev
、chapter
等)。
关系可以手动添加到页面对象中,或通过遍历辅助函数中注册的容器来找到。方法findRelation($page, $rel, $type)
将首先尝试通过调用$page>findRel($type)
或$page>findRel($type)
从$page
中找到给定的$rel
类型的$type
。如果$page
有一个可以转换为页面实例的关系,则将使用该关系。如果$page
实例没有指定的$type
,辅助函数将查找辅助函数中名为search$rel$type
(例如,searchRelNext()
或searchRevAlternate()
)的方法。如果存在这样的方法,它将用于通过遍历容器来确定$page
的关系。
并非所有关系都可以通过遍历容器来确定。以下是通过搜索找到的关系
searchRelStart()
,正向start
关系:容器中的第一个页面。searchRelNext()
,正向next
关系;找到容器中的下一个页面,即活跃页面之后的页面。searchRelPrev()
,正向prev
关系;找到上一个页面,即活跃页面之前的页面。searchRelChapter()
,正向chapter
关系;找到级别0上的所有页面,除了start
关系或如果它在级别0上,则是活跃页面。searchRelSection()
,正向section
关系;如果活跃页面在级别0(一个chapter
),则找到活跃页面的所有子页面。searchRelSubsection()
,正向subsection
关系;如果活跃页面在级别1(一个section
),则找到活跃页面的所有子页面。searchRevSection()
,反向section
关系;如果活跃页面在级别1(一个section
),则找到活跃页面的父页面。searchRevSubsection()
,反向subsection
关系;如果活跃页面在级别2(一个subsection
),则找到活跃页面的父页面。
允许的关系类型
在查找页面实例中的关系时(
$page->getRel($type)
或$page>getRev($type)
),辅助函数接受类型为string
、array
、Traversable
或Mezzio\Navigation\Page\PageInterface
的值。
- 直接使用
PageInterface
实例。- 如果找到一个字符串,它将被转换为
Mezzio\Navigation\Page\Uri
。- 如果找到数组或可遍历对象,它将被转换为一个或多个页面实例。如果第一个键是数字,则认为它包含多个页面,每个元素都将传递给页面工厂。如果第一个键不是数字,则直接将值传递给页面工厂,并返回一个单独的页面。
辅助工具还支持用于查找关系的魔法方法。例如,要查找正向备用关系,请调用$helper->findRelAlternate($page)
,要查找反向章节关系,请调用$helper->findRevSection($page)
。这些调用分别对应于$helper->findRelation($page, 'rel', 'alternate')
和$helper->findRelation($page, 'rev', 'section')
。
要自定义应渲染哪些关系,辅助工具使用渲染标志。渲染标志是一个整数值,它将与辅助工具的渲染常量进行位与(&)运算,以确定是否渲染属于渲染常量的关系。
请参阅以下示例以获取更多信息。
LinksInterface
辅助工具定义了以下常量
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_ALTERNATE
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_STYLESHEET
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_START
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_NEXT
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_PREV
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_CONTENTS
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_INDEX
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_GLOSSARY
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_COPYRIGHT
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_CHAPTER
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_SECTION
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_SUBSECTION
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_APPENDIX
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_HELP
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_BOOKMARK
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_CUSTOM
Mezzio\Navigation\Helper\Navigation\LinksInterface::RENDER_ALL
从RENDER_ALTERNATE
到RENDER_BOOKMARK
的常量表示标准的HTML链接类型。RENDER_CUSTOM
表示在页面中指定的非标准关系。RENDER_ALL
表示标准和非标准关系。
链接辅助工具中的方法
基本用法
在页面中指定关系
此示例显示了如何在页面中指定关系。
use Laminas\Config\Config; use Mimmi20\Mezzio\Navigation\Navigation; use Mimmi20\Mezzio\Navigation\Page\PageInterface; $container = new Navigation([ [ 'label' => 'Relations using strings', 'rel' => [ 'alternate' => 'http://www.example.org/', ], 'rev' => [ 'alternate' => 'http://www.example.net/', ], ], [ 'label' => 'Relations using arrays', 'rel' => [ 'alternate' => [ 'label' => 'Example.org', 'uri' => 'http://www.example.org/', ], ], ], [ 'label' => 'Relations using configs', 'rel' => [ 'alternate' => new Config([ 'label' => 'Example.org', 'uri' => 'http://www.example.org/', ]), ], ], [ 'label' => 'Relations using pages instance', 'rel' => [ 'alternate' => (new PageFactory())->factory([ 'label' => 'Example.org', 'uri' => 'http://www.example.org/', ]), ], ], ]);
链接的默认渲染
此示例显示了如何从在视图辅助工具中注册的容器中渲染菜单。
在视图脚本或布局中
<?= $this->navigation()->links() ?>
输出
<link rel="alternate" href="/products/server/faq/format/xml"> <link rel="start" href="/" title="Home"> <link rel="next" href="/products/server/editions" title="Editions"> <link rel="prev" href="/products/server" title="Foo Server"> <link rel="chapter" href="/products" title="Products"> <link rel="chapter" href="/company/about" title="Company"> <link rel="chapter" href="/community" title="Community"> <link rel="canonical" href="http://www.example.com/?page=server-faq"> <link rev="subsection" href="/products/server" title="Foo Server">
指定要渲染哪些关系
此示例显示了如何指定要查找和渲染的关系。
仅渲染开始、下一页和上一页
use Mimmi20\Mezzio\Navigation\Helper\Navigation\LinksInterface; $links = $this->navigation()->links(); $links->setRenderFlag(LinksInterface::RENDER_START | LinksInterface::RENDER_NEXT | LinksInterface::RENDER_PREV); echo $links;
输出
<link rel="start" href="/" title="Home"> <link rel="next" href="/products/server/editions" title="Editions"> <link rel="prev" href="/products/server" title="Foo Server">
仅渲染原生链接类型
$links->setRenderFlag(LinksInterface::RENDER_ALL ^ LinksInterface::RENDER_CUSTOM); echo $links;
输出
<link rel="alternate" href="/products/server/faq/format/xml"> <link rel="start" href="/" title="Home"> <link rel="next" href="/products/server/editions" title="Editions"> <link rel="prev" href="/products/server" title="Foo Server"> <link rel="chapter" href="/products" title="Products"> <link rel="chapter" href="/company/about" title="Company"> <link rel="chapter" href="/community" title="Community"> <link rev="subsection" href="/products/server" title="Foo Server">
除了章节之外,渲染所有内容
$links->setRenderFlag(Links::RENDER_ALL ^ Links::RENDER_CHAPTER); echo $links;
输出
<link rel="alternate" href="/products/server/faq/format/xml"> <link rel="start" href="/" title="Home"> <link rel="next" href="/products/server/editions" title="Editions"> <link rel="prev" href="/products/server" title="Foo Server"> <link rel="canonical" href="http://www.example.com/?page=server-faq"> <link rev="subsection" href="/products/server" title="Foo Server">
菜单
menu()
辅助工具用于从导航容器中渲染菜单。默认情况下,菜单将使用HTML UL
和LI
标签进行渲染,但辅助工具还允许使用部分视图脚本。
菜单辅助工具中的方法
以下为renderMenu()
方法所认可的选择项
基本用法
此示例显示了如何从视图辅助工具中注册/找到的容器中渲染菜单。请注意,页面根据可见性和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>
在部分视图脚本中使用访问控制列表(ACL)
如果您想在部分视图脚本中使用ACL,那么您将不得不手动检查对页面的访问权限。
在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; } }
视图辅助器 - 网站地图
sitemap()
辅助器用于生成XML网站地图,该地图由Sitemaps XML格式定义。关于网站地图的更多信息,请参阅维基百科上的网站地图。
默认情况下,网站地图辅助器使用网站地图验证器验证每个渲染的元素。这可以通过调用$helper->setUseSitemapValidators(false)
来禁用。
网站地图XML元素
仅在启用时进行验证
如果您禁用网站地图验证器,则不会验证自定义属性(见表格)。
网站地图辅助器还支持对生成的网站地图进行Sitemap XSD模式验证。默认情况下,这是禁用的,因为它将需要请求模式文件。可以通过$helper->setUseSchemaValidation(true)
来启用。
网站地图辅助器中的方法
基本用法
本例演示了如何根据我们上面所做的设置渲染XML网站地图。
// In a view script or layout: // format output $this->navigation() ->sitemap() ->setFormatOutput(true); // default is false // Other possible methods: // ->setUseXmlDeclaration(false); // default is true // ->setServerUrl('http://my.otherhost.com'); // default is to detect automatically // print sitemap echo $this->navigation()->sitemap();
注意如何过滤掉不可见的页面或与视图辅助器不兼容的ACL角色的页面
<?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"> <url> <loc>http://www.example.com/</loc> </url> <url> <loc>http://www.example.com/products</loc> </url> <url> <loc>http://www.example.com/products/server</loc> </url> <url> <loc>http://www.example.com/products/server/faq</loc> </url> <url> <loc>http://www.example.com/products/server/editions</loc> </url> <url> <loc>http://www.example.com/products/server/requirements</loc> </url> <url> <loc>http://www.example.com/products/studio</loc> </url> <url> <loc>http://www.example.com/products/studio/customers</loc> </url> <url> <loc>http://www.example.com/products/studio/support</loc> </url> <url> <loc>http://www.example.com/company/about</loc> </url> <url> <loc>http://www.example.com/company/about/investors</loc> </url> <url> <loc>http://www.example.com/company/news</loc> </url> <url> <loc>http://www.example.com/company/news/press</loc> </url> <url> <loc>http://www.example.com/archive</loc> </url> <url> <loc>http://www.example.com/community</loc> </url> <url> <loc>http://www.example.com/community/account</loc> </url> <url> <loc>http://forums.example.com/</loc> </url> </urlset>
不使用ACL角色进行渲染
不使用ACL角色渲染网站地图(应该过滤掉/community/account
)
echo $this->navigation()->sitemap() ->setFormatOutput(true) ->setRole();
输出
<?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"> <url> <loc>http://www.example.com/</loc> </url> <url> <loc>http://www.example.com/products</loc> </url> <url> <loc>http://www.example.com/products/server</loc> </url> <url> <loc>http://www.example.com/products/server/faq</loc> </url> <url> <loc>http://www.example.com/products/server/editions</loc> </url> <url> <loc>http://www.example.com/products/server/requirements</loc> </url> <url> <loc>http://www.example.com/products/studio</loc> </url> <url> <loc>http://www.example.com/products/studio/customers</loc> </url> <url> <loc>http://www.example.com/products/studio/support</loc> </url> <url> <loc>http://www.example.com/company/about</loc> </url> <url> <loc>http://www.example.com/company/about/investors</loc> </url> <url> <loc>http://www.example.com/company/news</loc> </url> <url> <loc>http://www.example.com/company/news/press</loc> </url> <url> <loc>http://www.example.com/archive</loc> </url> <url> <loc>http://www.example.com/community</loc> </url> <url> <loc>http://forums.example.com/</loc> </url> </urlset>
使用最大深度进行渲染
使用最大深度为1渲染网站地图。
echo $this->navigation()->sitemap() ->setFormatOutput(true) ->setMaxDepth(1);
输出
<?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"> <url> <loc>http://www.example.com/</loc> </url> <url> <loc>http://www.example.com/products</loc> </url> <url> <loc>http://www.example.com/products/server</loc> </url> <url> <loc>http://www.example.com/products/studio</loc> </url> <url> <loc>http://www.example.com/company/about</loc> </url> <url> <loc>http://www.example.com/company/about/investors</loc> </url> <url> <loc>http://www.example.com/company/news</loc> </url> <url> <loc>http://www.example.com/community</loc> </url> <url> <loc>http://www.example.com/community/account</loc> </url> <url> <loc>http://forums.example.com/</loc> </url> </urlset>
默认使用UTF-8编码
默认情况下,laminas-view使用UTF-8作为其默认编码。如果您想在
Sitemap
中使用其他编码,您需要做三件事
- 创建一个自定义渲染器并实现
getEncoding()
方法。- 创建一个自定义渲染策略,该策略将返回您的自定义渲染器实例。
- 在
ViewEvent
中附加自定义策略。请参阅HeadStyle文档中的示例,了解如何实现这一点。
许可
本软件包使用MIT许可。
请参阅LICENSE.md
。