Search code examples
symfonymenuknpmenu

Specify current route or template as active link KnpMenu


In symfony2, as describe above, I want to set the specified menu child as active status in Controller or Template, how can I achieve that? That is to say, I want several routes (controller action, template) map to one menu child, is that possible? I guess I could get the menu in controller or template and set it to active.


Solution

  • This is already implemented when using KNPMenuBundle. Classes are automatically generated for first last and current elements.


    Your menu will automatically look like this:

    <ul>
        <li class="first">
            <a href="/whatever1">Menu Level 1</a>        
        </li>
        <li class="current">
            <a href="/whatever2">Menu Level 2</a>        
        </li>
        <li class="last">
           <a href="/whatever3">Menu Level 3</a>
        </li>
    </ul>
    

    Assuming that you use Menu builder this way:

    //src/Acme/YourBundle/Menu/MenuBuilder.php
    public function createSimpleMenu(Request $request)
        {
            $menu = $this->factory->createItem('root');
            $menu->setCurrentUri($request->getRequestUri());
    
            $menu->addChild('Menu Level 1', array('route' => '_route_whatever1'));
            $menu->addChild('Menu Level 2', array('route' => '_route_whatever2'));
            $menu->addChild('Menu Level 3', array('route' => '_route_whatever3'));
    
            return $menu;
        }
    

    Therefore, you need to apply the css to current instead of active. As you can see, the job is realised by $menu->setCurrentUri($request->getRequestUri());.

    If you wish to customize manually your menu (in your case, you want to have several routes that map to the same element) you can use a switch statement:

    //src/Acme/YourBundle/Menu/MenuBuilder.php
    public function createSimpleMenu(Request $request)
    {
    // YOUR MENU AS USUAL FIRST
    // ...
    // A SWITCH IF YOU WISH TO CUSTOMIZE MANUALLY
    switch($request->get('_route')) {
        case "_route_whatever1bis":
            $menu['Menu Level 1']->setCurrent(true);
            break;
        case "_route_whatever2bis":
            $menu['Menu Level 2']->setCurrent(true);
            break;
        case "_route_whatever3bis":
            $menu['Menu Level 3']->setCurrent(true);
            break;
        }
    return $menu;
    }
    

    Note: To customize the way KNP Menu Bundle renders your menu, override knp_menu.html.twig. You can see the procedure here.