YII2中如何建立动态菜单

How to build dynamic menu in YII2

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

我目前是这样做的。

          <?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 方法来检查用户是否具有查看链接的正确权限。

Yii2 模板附带 Bootstrap 3,Nav 小部件最常用于构建菜单。

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

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

        ...
    ],
]);

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

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

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

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

$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,
]);

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

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

但如果 R​​BAC authManagerDbManager 并关闭缓存,将执行额外的查询,我们有点重复代码。

所以你可以这样做:

$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 小部件并实现此逻辑。

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

$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,
]);

使用这个:动态 2 级菜单项 yii2

$menuItems = array();
                $pages_record = Pages::find()->all();
                $i = 0;
                foreach ($pages_record as $data) 
                {
                    if($data->select_parent == 0)
                    {
                        $path = \Yii::$app->request->BaseUrl."/index.php?r=".$data->seo_url;
                        $menuItems[$i] = array('label' => $data->page_title, 'url' => $path);
                        $pages_sub_rec = Pages::findAll(['select_parent' => $data['pid']]);
                        foreach ($pages_sub_rec as $sub_value)
                        {
                            $menuItems[$i]['items'][] = array('label' => $sub_value->page_title, 'url' => '#');
                        }
                        $i++;
                    }
                }

我建议

composer requiere pceuropa/yii2-menu dev-master

我用的是简单的。
数据库:菜单和子菜单
加入:menu_id(子菜单)到 id(菜单)

``

<ul>
      $mainmenu = \common\models\Menu::find()->all();
                foreach ($mainmenu as $data)
      {
          echo "<li><a  href='$data->url'>$data->name_en</a><ul>";
          $sub_menu = \common\models\Childmenu::find()->where(['menu_id'=>$data->id])->all();
          foreach ($sub_menu as $sub_value)
          {
              echo "<li><a  href='$sub_value->url'>$sub_value->name_en</a></li>";
          }
          echo "</ul></li>";
      }
?></ul>

```