可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I used the following code to display the menu items.
Here by default the 'Home' link should be activated. So that i used the code
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)
),
));
I referred the url http://www.yiiframework.com/doc/api/1.1/CMenu#activateItems-detail
But i dont know how to use these parameters. Please help
回答1:
Not the Yii way, but the (simpler) jQuery way:
// 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");
}
});
回答2:
The code you give will be typically found inside a view. The documentation for view states that
Inside the view script, we can access the controller instance using
$this
. We can thus pull in any property of the controller by
evaluating $this->propertyName
in the view.
So, we have established that in the current context, $this->id
refers to the CController::id
property. This id will typically be the prefix of your controller's class name. For example, inside MyController
you will have $this->id == "my"
.
With all this in mind, you can now tell that active
will be true
if and only if the current view is rendered from inside a controller named DefaultController
. However, from the url
property of that menu item we see that the associated controller for that action (assuming default routing) is PostController
. So the $this->id == "default"
idea is faulty.
If you want to make the "Home" item active whenever any action in your PostController
is running, you should change this to $this->id == "post"
. Normally it should not be necessary to do this, because the activateItems
property (which defaults to true
) used with default routing will take into account both the controller id and the current action to determine which menu item to make active.
回答3:
if you have some advanced link structure, put method below in Controller
/**
* 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',
)),
),
回答4:
I used this way:
array('label'=>'Contact', 'url'=>array('site/contact'), 'active'=>strpos(Yii::app()->request->requestUri, Yii::app()->createUrl('site/contact'))===0)
回答5:
The menu will work as we use default pages as site/contact, site/login
But many times it will not work for the module url.
suppose i have module user and i had login action in login controller, so i can do below thing form menu as how menu item gets active defined below.
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
So, we can have problem to beautify url..
回答6:
For yiistarterkit just add this code in the _base.php file:
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;
}
And then use:
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'])],
]
]);
回答7:
Take as a base the file yiisoft/yii2-boostrap/nav.php function renderItem():
...
if ($this->activateItems && $active) {
Html::addCssClass($options, 'active');
}
return Html::tag('li', Html::a($label, $url, $linkOptions) . $items, $options);
And modify $option on $linkOption for a link.
Html::addCssClass($linkOptions, 'active');
As result active class will be added to a.class, instead li.class