Usar KnpMenuBundle para administrar los menús

KnpMenuBundle es un bundle muy útil para administrar los menús de tu aplicación y es muy fácil de instalar

Desde la documentación oficial de Symfony se pueden leer los pasos necesarios para instalar KnpMenuBundle, aunque es un bundle creado por KnpLabs.

Lo primero que hay que hacer es descargar el bundle. Utilizando composer:

composer require knplabs/knp-menu-bundle "dev-master"

Activamos el bundle añadiéndolo en el archivo app/AppKernel.php:

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...
            new Knp\Bundle\MenuBundle\KnpMenuBundle(),
        );
        // ...
    }
    // ...
}

Crear un menú con KnpMenuBundle

Hay dos métodos para crear menús con KnpMenuBundle, uno sencillo y uno más complicado pero más flexible. En este artículo de momento sólo voy a explicar el método sencillo:

Método sencillo

Para crear un menú, crea una nueva clase en el directorio Menú de uno de tus bundles. Esta clase tendrá un método por cada uno de los menús que quieras crear. Un ejemplo de menú es el siguiente:

// src/AppBundle/Menu/Builder.php
namespace AppBundle\Menu;

use Knp\Menu\FactoryInterface;
use Symfony\Component\DependencyInjection\ContainerAware;

class Builder extends ContainerAware
{
    public function mainMenu(FactoryInterface $factory, array $options)
    {
        $menu = $factory->createItem('root');

        $menu->addChild('Inicio', array('route' => 'inicio'));

        // Accede a los servicios desde el contenedor:
        $em = $this->container->get('doctrine')->getManager();
        // findMostRecent y Blog son ejemplos
        $blog = $em->getRepository('AppBundle:Blog')->findMostRecent();

        $menu->addChild('Ultimas entradas del blog', array(
            'route' => 'blog_mostrar',
            'routeParameters' => array('id' => $blog->getId())
        ));

        // Creando otro apartado del menú:
        $menu->addChild('Sobre mí', array('route' => 'sobremi'));
        // Puedes también añadir subniveles a tus menús:
        $menu['Sobre mi']->addChild('Editar perfil', array('route' => 'editar_perfil'));

        // ... puedes añadir más subniveles...
        return $menu;
    }
}

Con la plantilla standard de _knpmenu.html.twig el resultado anterior quedaría así:

<ul>
    <li class="current first">
        <a href="#route_to/inicio">Inicio</a>
    </li>
    <li class="current_ancestor">
        <a href="#route_to/page_show/?id=42">Sobre mi</a>
        <ul class="menu_level_1">
            <li class="current first last">
                <a href="#route_to/editar_perfil">Editar perfil</a>
            </li>
        </ul>
    </li>
</ul>

Y en la plantilla sólo tendrías que añadir:

{{ knp_menu_render('AppBundle:Builder:mainMenu') }}