如何在YII2中构建动态菜单 [英] How to build dynamic menu in YII2

查看:31
本文介绍了如何在YII2中构建动态菜单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个基于用户许可的动态菜单.例如,管理员帐户和基本帐户都有一个菜单.

I want to have a dynamic menu base on the user's permission. For example there is a menu for the admin account and for the basic account.

我目前正在这样做.

          <?php

            if((yii::$app->user->can('admin')) || (yii::$app->user->can('blah')) || (yii::$app->user->can('blahblah'))) ..and so on
            {
                //..print the menu 
            }

            //another condition for menu here.
            ?>

if 条件有捷径吗?比如说,我声明了一个内部有权限的数组,然后我将只使用 in_array 方法来检查用户是否具有查看链接的正确权限.

Is there a shortcut in that if condition? say for example I declare an array with the permissions inside then i will just use in_array method to check if the user has the right permission to see the links.

推荐答案

Yii2 模板随 Bootstrap 3 和 Nav 小部件最常用于构建菜单.

Yii2 templates ships with Bootstrap 3, and Nav widget is most often used for building menus.

以下是动态声明菜单项可见性的示例:

Here is an example of declaring visibility of menu items dynamically:

echo Nav::widget([
    'options' => ['class' => 'navbar-nav navbar-right'],
    'items' => [
        [
            'label' => 'Users',
            'url' => ['/users'],
            'visible' => Yii::$app->user->can('users.manage'),
        ],

        ...
    ],
]);

而且您不需要检查每个可能的角色,您需要检查访问/管理特定部分的权限.

And you don't need to check every possible role, you need to check permission for accessing / managing specific section.

例如,在提供的示例中,每个具有分配权限的用户 users.manage 都可以查看该菜单项.因此,添加权限并将其分配给所需的用户角色.

For example in the provided example every user with assigned permission users.manage can view that menu item. So, add permssion and assign it to desired user roles.

不要忘记检查控制器中的权限,如果链接仍然可以访问,将其隐藏在布局中没有意义.

Don't forget to check permissions in controller too, hiding it in layout doesn't make sense if the link is still accessible.

有时您有包含分组项目的嵌套子菜单,并且您也希望根据权限有条件地显示它.你可以这样做:

Sometimes you have the nested submenu with grouped items and you want to show it conditionally too, depending on the rights. You can do it like that:

$menuItems = [
    [
        'label' => 'Section',
        'items' => [
            [
                'label' => 'Subsection One',
                'url' => ['/sub-section-one/index']],
                'visible' => Yii::$app->user->can('sub-section-one.manage'),
            ],
            [
                'label' => 'Subsection One',
                'url' => ['/sub-section-one/index']],
                'visible' => Yii::$app->user->can('sub-section-two.manage'),
            ],
        ],
    ],
],

echo Nav::widget([
    'options' => ['class' => 'navbar-nav navbar-right'],
    'items' => $menuItems,
]);

问题是如果用户没有管理这两个子部分的权限,用于分组的根部分仍然可见.我们显然可以添加

The problem is if user didn't have permission for managing both subsections, the root section used for grouping is still visible. We obviously can add

'visible' => Yii::$app->user->can('sub-section-one.manage') || Yii::$app->user->can('sub-section-two.manage'),

但是如果 RBAC authManagerDbManager 并关闭缓存,将执行额外的查询,我们会复制代码.

But in case of RBAC authManager being DbManager and turned off caching additional queries will be performed and we kind of duplicating code.

所以你可以这样做:

$sectionItems => [
    [
        'label' => 'Subsection One',
        'url' => ['/sub-section-one/index']],
        'visible' => Yii::$app->user->can('sub-section-one.manage'),
    ],
    [
        'label' => 'Subsection One',
        'url' => ['/sub-section-one/index']],
        'visible' => Yii::$app->user->can('sub-section-two.manage'),
    ],
],

$isSectionVisible = false;

foreach ($sectionItems as $sectionItem) {
    if ($sectionItem['visible']) {
        $isSectionVisible = true;

        break;
    }
}

然后:

$menuItems = [
    [
        'label' => 'Section',
        'visible' => $isSectionVisible,
        'items' => $sectionItems,
    ],
],

echo Nav::widget([
    'options' => ['class' => 'navbar-nav navbar-right'],
    'items' => $menuItems,
]);

或者您可以扩展 Nav 小部件并实现此逻辑.

Or you can extend Nav widget and implement this logic.

另外看看高级模板layout,还有一个构建动态菜单的例子:

Also take a look at advanced template layout, there is also an example for building dynamic menu:

$menuItems = [
    ['label' => 'Home', 'url' => ['/site/index']],
];
if (Yii::$app->user->isGuest) {
    $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']];
} else {
    $menuItems[] = '<li>'
        . Html::beginForm(['/site/logout'], 'post')
        . Html::submitButton(
            'Logout (' . Yii::$app->user->identity->username . ')',
            ['class' => 'btn btn-link']
        )
        . Html::endForm()
        . '</li>';
}
echo Nav::widget([
    'options' => ['class' => 'navbar-nav navbar-right'],
    'items' => $menuItems,
]);

这篇关于如何在YII2中构建动态菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆