Question

I've put together a menu in Yii (my first project using it) like this:

$this->widget('zii.widgets.CMenu',array(
    'items'=>array(
        array('label'=>'Home', 'url'=>array('/')),
        array('label'=>'Examples', 'url'=>array('/examples')),
        array('label'=>'Contact', 'url'=>array('/contact')),
        array('label'=>'FAQ', 'url'=>array('/faq')),
        array('label'=>'Blog', 'url'=>array('/blog')),
        array('label'=>'Order', 'url'=>array('/order')),
    ),
));

Each of those URL paths, such as /examples is a route defined in my config so that it doesn't look like site/examples.

For the Home link, I'm trying to get it to just link to the root level of the site. Apparently, the CMenu widget passes the URL through CHtml::normalizeUrl() first which ends up making it point at the current page. So if I am on the examples page, the home link points to /examples.

This is what normalizeUrl() says it does:

If the input parameter is an empty string, the currently requested URL will be returned.

If the input parameter is a non-empty string, it is treated as a valid URL and will be returned without any change.

If the input parameter is an array, it is treated as a controller route and a list of GET parameters, and the CController::createUrl method will be invoked to create a URL.

I've tried passing an empty string and it ends up pointing to the current request URL as expected. I've tried passing "/" which is a non-empty string and it still points to the current request URL. I've also tried passing it an array and it dies with trim() expects parameter 1 to be string, array given because the CMenu is expecting a string.

I'm trying to do things the Yii way but I'm seriously about to just leave the menu static if it can't address something as simple as going back to the home page.

TL;DR How can I make the CMenu widget in Yii create a link to "/" or to the base domain?

Was it helpful?

Solution

When you use array as url it will try to create url based on your router config, but if you pass string as param it will be passed literally, ie:

$this->widget('zii.widgets.CMenu',array(
    'items'=>array(
        // Root hardcoded
        array('label'=>'Home', 'url'=>'/'),
        // Root dynamic (works also if not in domain root)
        array('label'=>'Home', 'url'=>Yii::app()->baseUrl),
        // External url
        array('label'=>'Examples', 'url'=> 'http://example.com/'),
        // current url
        array('label'=>'Contact', 'url'=> ''),
        array('label'=>'FAQ', 'url'=>array('/faq')),
        array('label'=>'Blog', 'url'=>array('/blog')),
        array('label'=>'Order', 'url'=>array('/order')),
    ),
));

Oh, and thats rule for all places when you can use url.

OTHER TIPS

array('label'=>'Home', 'url'=>Yii::app() -> request -> baseUrl)

Another option

array('label'=>'Home', 'url'=>Yii::app()->homeUrl)

This helps if your baseUrl is not your homeUrl.

get an Absolute webroot url, and strip the http[s]://

array('label'=>'Home', 'url'=>Yii::app()->getBaseUrl(true)),
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top