yii2-bootstrap
yii2-bootstrap copied to clipboard
Automatically hide parent 'yii\bootstrap\Nav' section if all subitems are hidden
Consider this example.
$menuItems = [
[
'label' => 'Miscellaneous',
'items' => [
[
'label' => 'Users',
'url' => ['/users/index'],
'visible' => Yii::$app->user->can('users.manage'),
],
[
'label' => 'Slides',
'url' => ['/slides/index'],
'visible' => Yii::$app->user->can('slides.manage'),
],
[
'label' => 'News,
'url' => ['/news/index'],
'visible' => Yii::$app->user->can('news.manage'),
],
],
],
];
echo Nav::widget([
'options' => ['class' => 'navbar-nav navbar-right'],
'items' => $menuItems,
]);
If the user doesn't have permissions to manage users, slides and news, Miscellaneous
section will be still shown, but it doesn't make sense because it doesn't have a link (click triggers visibility of subitems).
To conditionally hide it we have to add something like this to parent section:
'visible' => Yii::$app->user->can('users.manage') ||
Yii::$app->user->can('slides.manage') ||
Yii::$app->user->can('news.manage'),
This is clean violation of DRY principle. Obviously we can have a helper method for checking that, but still we need to list permissions in both places, It's better to be done inside Nav widget itself.
So, if parent section have all subitems with visible
property set and visible
equals false
in all subitems, we can just skip rendering of this whole section.
Yep, that makes sense.
OK, I will try to send a PR in this case.
Done.
You all forget that \yii\bootstrap\Dropdown
supports items specified as a string:
/**
* @var array list of menu items in the dropdown. Each array element can be either an HTML string,
* or an array representing a single menu with the following structure:
* ...
* To insert divider use `<li role="presentation" class="divider"></li>`.
*/
public $items = [];
Currently such items are considered always visible. So if the OP were to put a divider in his example, the Nav won't be hidden which is not what a user would expect from this additional functionality.