Skip to content

Menus

Add a menu in a template

In your twig template, use the chill_menu function :

{{ chill_menu('person', {
    'layout': '@ChillPerson/menu.html.twig',
    'args': { 'person_id': person.id, 'person': person },
}) }}

The available arguments are:

  • layout : a custom layout template. Defaults to @ChillMain/Menu/defaultMenu.html.twig.
  • args : those arguments will be passed to each builder as the $parameters array.

Create an entry in a menu

To add entries to a menu, implement Chill\MainBundle\Routing\LocalMenuBuilderInterface:

use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Knp\Menu\MenuItem;

final class MyMenuBuilder implements LocalMenuBuilderInterface
{
    public static function getMenuIds(): array
    {
        return ['person'];
    }

    public function buildMenu($menuId, MenuItem $menu, array $parameters): void
    {
        $menu->addChild('My entry', [
            'route' => 'my_route',
            'routeParameters' => [
                'person_id' => $parameters['person']->getId(),
            ],
        ])->setExtras([
            'order' => 200,
        ]);
    }
}
  • getMenuIds() returns the list of menu identifiers this builder contributes to. The identifiers correspond to the first argument of chill_menu in Twig.
  • buildMenu() receives:
  • $menuId : the menu identifier (useful when a builder handles multiple menus).
  • $menu : the MenuItem to add children to, using KnpMenu's API.
  • $parameters : the args array passed in the chill_menu Twig call.

The service is automatically registered thanks to Symfony's autoconfiguration: any class implementing LocalMenuBuilderInterface gets tagged with chill.menu_builder and injected into the menu system — no manual service configuration is needed.

For the order extra, prefer large increments (10, 50, 100, ...) to leave room for future entries.

A builder can also receive injected services through the constructor, for example to check access rights or translate labels (see PersonMenuBuilder for a complete example).

Menu ID args parameters Context
person person (Person entity) Person detail pages
household household (Household entity) Household detail pages
accompanyingCourse accompanyingCourse (AccompanyingPeriod entity) Accompanying course pages
person_quick_menu person (Person entity) Person list rows
accompanying_course_quick_menu accompanying-course (AccompanyingPeriod entity) Accompanying course list rows
section (none) Top navigation bar — sections
user (none) Top navigation bar — user menu

Customize menu rendering

You can change the Twig template used to render a menu by passing a layout option to chill_menu:

{{ chill_menu('person', {
    'layout': '@MyBundle/my_custom_menu.html.twig',
    'args': { 'person': person },
}) }}

The template receives a menu variable which is a KnpMenu ItemInterface.

Remove an existing menu item

When building an application on top of chill-bundles, you may want to remove entries added by a bundle. Implement LocalMenuBuilderInterface for the same menu ID, declare a low priority via getDefaultPriority() so your builder runs after the bundle builders, then call removeChild() by the item's name:

use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Knp\Menu\MenuItem;

final class MyPersonMenuOverride implements LocalMenuBuilderInterface
{
    public static function getMenuIds(): array
    {
        return ['person'];
    }

    public static function getDefaultPriority(): int
    {
        return -100;
    }

    public function buildMenu($menuId, MenuItem $menu, array $parameters): void
    {
        $menu->removeChild('Person duplicate');
    }
}

getDefaultPriority() controls the order in which builders run: a lower value means the builder runs later, after builders with a higher priority (default is 0). This ensures the item has already been added before your builder removes it.

The string passed to removeChild() must match the name given to the child when it was added (the first argument to addChild()).