Search code examples
symfonytwitter-bootstrap-3knpmenubundle

Dropdown Menus with KnpMenuBundle and Bootstrap 3


I've just added the KnpMenuBundle to my Symfony project. I also added Bootstrap to make it look nicer.

Now I want to create a Submenu or Dropdownmenu. Is there a simple example / way how to do this? I've searched a lot of examples but either they require an additional bundle or do not work

Update

I need to know how I have to add attributes to my menu children in order to render it with bootstrap

Best regards

Oliver


Solution

  • It's rather straightforward. For attributes, see the KnpMenu docs.

    An example:

    base.html.twig, which appears in templates with {% extends "base.html.twig" %}:

    ...
            {% block stylesheets %}
                <link href="{{ asset('css/bootstrap.css') }}" rel="stylesheet" media="all">
                <link href="{{ asset('css/pdf.css') }}" rel="stylesheet" media="all">
                <link href="{{ asset('css/jquery-ui.min.css') }}" rel="stylesheet" media="all" />
            {% endblock %}
    ...
        {% block nav %}
            {% spaceless %}
                <nav class="navbar navbar-default">
                    <div class="navbar-header">
                        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                            <span class="sr-only">Toggle navigation</span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                        </button>
                        <a class="navbar-brand" href="#"></a>
                    </div>
                    <div class="collapse navbar-collapse navbar-ex1-collapse">
                        {{ knp_menu_render('AppBundle:Builder:mainMenu', {'style': 'navbar'})  }}
                        {{ knp_menu_render('AppBundle:Builder:logoutMenu', { 'style': 'navbar-right' })  }}
                    </div>
                </nav>
            {% endspaceless %}
        {% endblock nav %}
    ...
            {% block javascripts %}
                <script
                    src="https://code.jquery.com/jquery-1.11.3.js"
                    integrity="sha256-IGWuzKD7mwVnNY01LtXxq3L84Tm/RJtNCYBfXZw3Je0="
                crossorigin="anonymous"></script>
                <script src="{{ asset('js/bootstrap.js') }}"></script>
                <script src="{{ asset('js/jquery-ui.min.js') }}"></script>
                <script src="{{ asset('js/project.js') }}"></script>
            {% endblock %}
    

    Builder.php:

        ...
        class Builder implements ContainerAwareInterface
        {
            use ContainerAwareTrait;
    
            public function mainMenu(FactoryInterface $factory, array $options)
            {
                $checker = $this->container->get('security.authorization_checker');
    
                $menu = $factory->createItem('root');
    
                $menu->addChild('Home', array('route' => 'homepage'));
    
                $menu->addChild('Receipt');
                $menu['Receipt']->addChild('Add receipt', [
                    'route' => 'receipt_add'
                ]);
                $menu['Receipt']->addChild('Edit receipt', [
                    'route' => 'receipt_edit'
                ]);
    
                $menu->addChild('Artist');
                $menu['Artist']->addChild('Add artist', [
                    'route' => 'artist_add'
                ]);
                $menu['Artist']->addChild('Edit artist', [
                    'route' => 'artist_edit'
                ]);
                $menu['Artist']->addChild('Add existing to show', [
                    'route' => 'existing_artists'
                ]);
    
                $menu->addChild('Tickets');
                $menu['Tickets']->addChild('Add block', [
                    'route' => 'block_add'
                ]);
                $menu['Tickets']->addChild('Edit block', [
                    'route' => 'block_edit'
                ]);
    
    
                $menu->addChild('Show');
                $menu['Show']->addChild('Add show', [
                    'route' => 'show_add'
                ]);
                $menu['Show']->addChild('Edit show', [
                    'route' => 'show_edit'
                ]);
    
                $menu->addChild('Reports', [
                    'route' => 'reports'
                ]);
    
                if ($checker->isGranted('ROLE_ADMIN')) {
                    $menu->addChild('Admin');
                    $menu['Admin']->addChild('Ticket block reassign', [
                        'route' => 'block_reassign'
                    ]);
                    $menu['Admin']->addChild('Users', [
                        'route' => 'easyadmin'
                    ]);
                    $menu['Admin']->addChild('Delete artist', [
                        'route' => 'artist_delete'
                    ]);
                }
    
                return $menu;
            }
    ...