自动设置活动项目
Set active item automatically
我的应用程序中有一个菜单:
<?php
NavBar::begin([
'brandLabel' => Html::img('@web/images/logo-top.png', ['id' => 'logo']),
'brandUrl' => Yii::$app->homeUrl,
'options' => [
'class' => 'navbar-inverse navbar-static-top',
],
]);
if (count($menuItems)) {
echo Nav::widget([
'options' => ['class' => 'navbar-nav'],
'items' => $menuItems,
]);
}
?>
<?php NavBar::end(); ?>
$menuItems
在一个Controller中生成:
private function constructMenu($categories) {
$menu = [];
if (is_array($categories) && (count($categories) > 0)) {
foreach($categories as $key => $category) {
$menu[$key] = [
'label' => $category['name'],
'url' => Url::to([
'category/view',
'slug' => $category['slug']
]),
];
if (is_array($category['children']) && (count($category['children']) > 0)) {
$menu[$key]['items'] = $this->constructMenu($category['children']);
}
}
}
return $menu;
}
我还有 urlManager 配置:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'category/<slug:[\w_-]+>' => 'category/view',
'item/<slug:[\w_-]+>' => 'item/view',
'cart/remove/<item_id:\d+>' => 'cart/remove',
'cart/add/<item_id:\d+>' => 'cart/add',
],
],
所以,唯一的问题是菜单项总是 active = false
。我应该如何修改 constructMenu
方法来为 active
键设置正确的值?或者我应该在模板中完成?
以下是来自 PhpStrom 调试面板的 $menuItems
的内容,就在它被传递给 Nav::widget
之前:
这是我现在所在的位置:
NavBar::begin([
'brandLabel' => Html::img('@web/images/logo-top.png',
['id' => 'logo', 'style' => 'height: 40px; filter: invert(100%);']),
'brandUrl' => Yii::$app->homeUrl,
'options' => [
'class' => 'navbar-inverse navbar-static-top',
],
]);
$controllerAndSlug = $this->context->id . '/' . $this->context->actionParams['slug'];
$menuItems = array_map(
function($item) use ($controllerAndSlug) {
$item['active'] = strpos($item['url'], $controllerAndSlug) !== false;
return $item;
},
$menuItems
);
if (count($menuItems)) {
echo Nav::widget([
'options' => ['class' => 'navbar-nav'],
'items' => $menuItems,
]);
}
NavBar::end();
它工作正常,但仅在顶级菜单项上设置 active
标志。现在我想知道如何将参数传递给 callback-function.
试试这个:
private function constructMenu($categories) {
$menu = [];
if (is_array($categories) && (count($categories) > 0)) {
foreach($categories as $key => $category) {
$menu[$key] = [
'label' => $category['name'],
'url' => Url::to([
'category/view',
'slug' => $category['slug']
]),
'active' => Yii::$app->controller->id == 'category'
&& Yii::$app->controller->action->id == 'view'
&& Yii::$app->request->get('slug') == $category['slug']
];
if (is_array($category['children']) && (count($category['children']) > 0)) {
$menu[$key]['items'] = $this->constructMenu($category['children']);
}
}
}
return $menu;
}
尽管如果您提供完整的 URL 和 /controller/action
格式,它应该可以工作,如果仍然不能,那么您可以使用 item
的 active
选项通过检查当前控制器、动作和 slug
protected function constructMenu($categories) {
$menu = [];
$controller = Yii::$app->controller->id;
$action = Yii::$app->controller->action->id;
$slug = Yii::$app->request->get('slug');
if( is_array($categories) && (count($categories) > 0) ){
foreach( $categories as $key => $category ){
$isActive = ($controller == 'category' && $action == 'view' && $slug == $category['slug']);
$menu[$key] = [
'label' => $category['name'],
'url' => Url::to([
'category/view',
'slug' => $category['slug']
]),
'active' => $isActive
];
if( is_array($category['children']) && (count($category['children']) > 0) ){
$menu[$key]['items'] = $this->constructMenu($category['children']);
}
}
}
return $menu;
}
我的应用程序中有一个菜单:
<?php
NavBar::begin([
'brandLabel' => Html::img('@web/images/logo-top.png', ['id' => 'logo']),
'brandUrl' => Yii::$app->homeUrl,
'options' => [
'class' => 'navbar-inverse navbar-static-top',
],
]);
if (count($menuItems)) {
echo Nav::widget([
'options' => ['class' => 'navbar-nav'],
'items' => $menuItems,
]);
}
?>
<?php NavBar::end(); ?>
$menuItems
在一个Controller中生成:
private function constructMenu($categories) {
$menu = [];
if (is_array($categories) && (count($categories) > 0)) {
foreach($categories as $key => $category) {
$menu[$key] = [
'label' => $category['name'],
'url' => Url::to([
'category/view',
'slug' => $category['slug']
]),
];
if (is_array($category['children']) && (count($category['children']) > 0)) {
$menu[$key]['items'] = $this->constructMenu($category['children']);
}
}
}
return $menu;
}
我还有 urlManager 配置:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'category/<slug:[\w_-]+>' => 'category/view',
'item/<slug:[\w_-]+>' => 'item/view',
'cart/remove/<item_id:\d+>' => 'cart/remove',
'cart/add/<item_id:\d+>' => 'cart/add',
],
],
所以,唯一的问题是菜单项总是 active = false
。我应该如何修改 constructMenu
方法来为 active
键设置正确的值?或者我应该在模板中完成?
以下是来自 PhpStrom 调试面板的 $menuItems
的内容,就在它被传递给 Nav::widget
之前:
这是我现在所在的位置:
NavBar::begin([
'brandLabel' => Html::img('@web/images/logo-top.png',
['id' => 'logo', 'style' => 'height: 40px; filter: invert(100%);']),
'brandUrl' => Yii::$app->homeUrl,
'options' => [
'class' => 'navbar-inverse navbar-static-top',
],
]);
$controllerAndSlug = $this->context->id . '/' . $this->context->actionParams['slug'];
$menuItems = array_map(
function($item) use ($controllerAndSlug) {
$item['active'] = strpos($item['url'], $controllerAndSlug) !== false;
return $item;
},
$menuItems
);
if (count($menuItems)) {
echo Nav::widget([
'options' => ['class' => 'navbar-nav'],
'items' => $menuItems,
]);
}
NavBar::end();
它工作正常,但仅在顶级菜单项上设置 active
标志。现在我想知道如何将参数传递给 callback-function.
试试这个:
private function constructMenu($categories) {
$menu = [];
if (is_array($categories) && (count($categories) > 0)) {
foreach($categories as $key => $category) {
$menu[$key] = [
'label' => $category['name'],
'url' => Url::to([
'category/view',
'slug' => $category['slug']
]),
'active' => Yii::$app->controller->id == 'category'
&& Yii::$app->controller->action->id == 'view'
&& Yii::$app->request->get('slug') == $category['slug']
];
if (is_array($category['children']) && (count($category['children']) > 0)) {
$menu[$key]['items'] = $this->constructMenu($category['children']);
}
}
}
return $menu;
}
尽管如果您提供完整的 URL 和 /controller/action
格式,它应该可以工作,如果仍然不能,那么您可以使用 item
的 active
选项通过检查当前控制器、动作和 slug
protected function constructMenu($categories) {
$menu = [];
$controller = Yii::$app->controller->id;
$action = Yii::$app->controller->action->id;
$slug = Yii::$app->request->get('slug');
if( is_array($categories) && (count($categories) > 0) ){
foreach( $categories as $key => $category ){
$isActive = ($controller == 'category' && $action == 'view' && $slug == $category['slug']);
$menu[$key] = [
'label' => $category['name'],
'url' => Url::to([
'category/view',
'slug' => $category['slug']
]),
'active' => $isActive
];
if( is_array($category['children']) && (count($category['children']) > 0) ){
$menu[$key]['items'] = $this->constructMenu($category['children']);
}
}
}
return $menu;
}