mimmi20 / mezzio-navigation-laminasviewrenderer-bootstrap

为Mezzio导航提供Bootstrap视图助手

2.0.6 2024-09-14 07:16 UTC

README

Latest Stable Version Latest Unstable Version License

代码状态

codecov Test Coverage Average time to resolve an issue Percentage of issues still open Mutation testing badge Maintainability

安装

运行

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\ 为前缀,后跟配置键的名称。这有助于确保不会与其他服务发生命名冲突。

以下示例演示了渲染名为 defaultspecialsitemap 的容器中的导航菜单。

<!-- ... -->

<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-acllaminas-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> &gt; <a href="/products/server">Foo Server</a> &gt; FAQ

指定缩进

此示例显示了如何渲染带有初始缩进的面包屑。

使用 8 个空格缩进渲染

<?= $this->navigation()->breadcrumbs()->setIndent(8) ?>

输出

        <a href="/products">Products</a> &gt; <a href="/products/server">Foo Server</a> &gt; 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 ULLI 标签进行渲染,但助手还允许使用部分视图脚本。

基本用法

此示例显示了如何从视图助手中注册/找到的容器中渲染菜单。注意,页面是基于可见性和 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 中使用其他编码,您需要做三件事

  1. 创建一个自定义渲染器并实现 getEncoding() 方法。
  2. 创建一个自定义渲染策略,该策略将返回你的自定义渲染器的实例。
  3. ViewEvent中附加自定义策略。

查看HeadStyle文档中的示例,了解如何实现此功能。

许可证

本软件包使用MIT许可证授权。

请参阅LICENSE.md