Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to identify active menu link in CakePHP

I'm creating an accordion layout for an admin sidebar. Now I need to identify the active link and add a class active to that link. Here is my code:

<div class="accordion-group">
<div class="accordion-heading">
    <a href="#collapseSeven" data-parent="#side_accordion" data-toggle="collapse" class="accordion-toggle">
        <i class="icon-th"></i> Gallery Manager
    </a>
</div>
<div class="accordion-body collapse" id="collapseSeven">
    <div class="accordion-inner">
        <ul class="nav nav-list">
            <li>
                <?php echo $this->Html->link('View All',array('controller' => 'gallaries', 'action' => 'index'));?>
            </li>
            <li>
                <?php echo $this->Html->link('Add New',array('controller' => 'gallaries', 'action' => 'add'));?>
            </li>
        </ul>
        </div>
    </div>
</div>

What is the best way to do this? Thanks in advance!

like image 504
Krishna Avatar asked Jul 30 '12 07:07

Krishna


2 Answers

I have found the solution :

$url = $this->Html->url('INPUT_THE_URL') ;
$active = $this->request->here == $url? true: false;
like image 149
Krishna Avatar answered Nov 09 '22 07:11

Krishna


To check whether a given URL is currently active in Cakephp 2.x, you should check if it's normalized (in the sense of Router::normalize()) form is the same as the normalized form of the currently requested URL (in the sense of $this->request->here).

$currentUrl = Router::normalize($this->request->here);
$checkedUrl = Router::normalize($myUrl);
$isActive = $currentUrl === $checkedUrl;

Sometimes you might want a loose matching to show a page as active in a menu, if a child is currently shown. Think you want to display your menu link to the fruits overview site at /fruits/ as active while surfing the Banana detail site at /fruits/banana/. You can achieve this easily by looking for a partial match only.

$isActive = (0 === strpos($currentUrl, $checkedUrl));

For sure your matching might get more complex, for example if you're heavily making use of named params and the like and want to reflect it in your menu, but you should find your way from here.

A solution for your particular problem might look like this:

$currentUrl = Router::normalize($this->request->here);
$links = array(
    array(
        'label' => __('View All'),
        'url' => array('controller' => 'galleries', 'action' => 'index'),
    ),
    array(
        'label' => __('Add New'),
        'url' => array('controller' => 'galleries', 'action' => 'add'),
    ),
    /* ... */
);

foreach ($links as $link) {
    $linkLabel = $link['label'];
    $linkUrl = Router::url($link['url']);
    $linkHtml = $this->Html->link($linkLabel, $linkUrl);

    $linkActive = $currentUrl === $linkUrl;

    echo $this->Html->tag('li', $linkHtml, array(
        'class' => $linkActive ? 'active' : '',
        'escape' => false, // to not escape anchor markup
    ));
}

To make your live just that tiny bit easier by not even thinking about this question, you could also use a Helper for menu creation that someone else built like torifat/cake-menu_builder.

like image 26
bfncs Avatar answered Nov 09 '22 06:11

bfncs