Yii如何突出显示当前菜单项


Yii how to highlight the current menu item

我使用以下代码来显示菜单项。

默认情况下,此处应激活"主页"链接。所以我用了代码

active' => $this->id =='default' ? true : false

$this->widget('zii.widgets.CMenu',array(
     'linkLabelWrapper' => 'span',
    'items'=>array(
    array('label'=>'Home', 'url'=>array('post/index'),'active'=>$this->id=='default'?true:false),
    array('label'=>'About', 'url'=>array('site/page', 'view'=>'about'),'active'=>$this->id=='about'?true:false),
    array('label'=>'Test', 'url'=>array('site/page', 'view'=>'test')),
    array('label'=>'Contact', 'url'=>array('site/contact')),
    array('label'=>'Login', 'url'=>array('site/login'), 'visible'=>Yii::app()->user->isGuest),
    array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('site/logout'), 'visible'=>!Yii::app()->user->isGuest)
    ),
    )); 

我引用了urlhttp://www.yiiframework.com/doc/api/1.1/CMenu#activateItems-细节但是我不知道如何使用这些参数。请帮助

不是Yii方式,而是(更简单的)jQuery方式:

// find menu-item associated with this page and make current:
$('a').each(function(index, value) { 
    if ($(this).prop("href") === window.location.href) {
        $(this).addClass("current-page");
    } 
});

您提供的代码通常会在视图中找到。查看文件指出

在视图脚本中,我们可以使用CCD_ 2。因此,我们可以通过评估视图中的CCD_ 3。

因此,我们已经确定,在当前上下文中,$this->id指的是CController::id属性。这个id通常是控制器类名的前缀。例如,在MyController中,将有$this->id == "my"

考虑到所有这些,现在可以判断active将是true,如果并且仅当当前视图是从名为DefaultController的控制器内部渲染的。然而,从该菜单项的url属性中,我们可以看到该操作的关联控制器(假设默认路由)是PostController。所以$this->id == "default"的想法是错误的。

如果您想在PostController中运行任何操作时激活"主页"项目,则应将其更改为$this->id == "post"。通常不需要这样做,因为用于默认路由的activateItems属性(默认为true)将同时考虑控制器id当前操作,以确定激活哪个菜单项。

如果您有一些高级链接结构,请将下面的方法放入控制器中

/**
 * Checks if the current route matches with given routes
 * @param array $routes
 * @return bool
 */
public function isActive($routes = array())
{
    $routeCurrent = '';
    if ($this->module !== null) {
        $routeCurrent .= sprintf('%s/', $this->module->id);
    }
    $routeCurrent .= sprintf('%s/%s', $this->id, $this->action->id);
    foreach ($routes as $route) {
        $pattern = sprintf('~%s~', preg_quote($route));
        if (preg_match($pattern, $routeCurrent)) {
            return true;
        }
    }
    return false;
}
//usage
'items'=>array(
    array('label'=>'Some Label', 'url'=>array('some/route'),'active'=>$this->isActive(array(
        'some/route',
        'another/route',        
    )),    
),

我使用了这种方式:

array('label'=>'Contact', 'url'=>array('site/contact'), 'active'=>strpos(Yii::app()->request->requestUri, Yii::app()->createUrl('site/contact'))===0)

菜单将工作,因为我们使用默认页面作为site/contact、site/login但很多时候它对模块url不起作用。

假设我有模块用户,并且我在登录控制器中有登录操作,所以我可以在下面定义的菜单项如何激活时,从菜单中执行以下操作。

array('label'=>Yii::t('frontend','Login'), 'url'=>array('/user/login/login'), 'visible'=>Yii::app()->user->isGuest), // Working, Login tag activated on login page
array('label'=>Yii::t('frontend','Login'), 'url'=>array('/user/login'), 'visible'=>Yii::app()->user->isGuest), // Not working, Login tag not activated on login page

所以,我们可能会遇到美化url的问题。。

对于yiistarterkit,只需在_base.php文件中添加以下代码:

function isActive($routes = array())
{
    if (Yii::$app->requestedRoute == "" && count($routes) == 0){
        return true;
    }
    $routeCurrent = Yii::$app->requestedRoute;
    foreach ($routes as $route) {
        $pattern = sprintf('~%s~', preg_quote($route));
        if (preg_match($pattern, $routeCurrent)) {
            return true;
        }
    }
    return false;
}

然后使用:

echo Nav::widget([
'options' => ['class' => 'navbar-nav navbar-left'],
'items' => [
    ['label' => 'Yii::t('frontend', 'Home'), 'url' => ['/'], 'active'=>isActive()],
    ['label' => 'Yii::t('frontend', 'Services'), 'url' => ['/services'], 'active'=>isActive(['services'])],
]
]);

以yiisoft/yii2 boostrap/nav.php函数renderItem()为基础:

...
if ($this->activateItems && $active) {
    Html::addCssClass($options, 'active');
}       
return Html::tag('li', Html::a($label, $url, $linkOptions) . $items, $options);

并修改链接的$linkOption上的$option。

Html::addCssClass($linkOptions, 'active');

因此,活动类将添加到.class,而不是li.class