diff --git a/docs/source/development/menus.md b/docs/source/development/menus.md index e4904ac54..df668b5e4 100644 --- a/docs/source/development/menus.md +++ b/docs/source/development/menus.md @@ -1,87 +1,130 @@ ###### Menus -Chill has created his own menu system - - [Routes dans Chill [specification] ](https://redmine.champs-libres.coop/issues/179) - The issue wich discussed the implementation of routes. - -## Concepts - - to be written +This document explains how to use and create menus in Chill. ## Add a menu in a template -In your twig template, use the `chill_menu` function : +In your twig template, use the `chill_menu` function: -```php - {{ chill_menu('person', { - 'layout': 'ChillPersonBundle::menu.html.twig', - 'args': {'id': person.id }, - 'activeRouteKey': 'chill_person_view' - }) }} +```twig +{{ chill_menu('person', { + 'layout': '@ChillPerson/menu.html.twig', + 'args' : {'person_id': person.id, 'person': person }, + 'activeRouteKey': activeRouteKey +}) }} ``` The available arguments are: -* `layout` : a custom layout. Default to `ChillMainBundle:Menu:defaultMenu.html.twig` -* `args` : those arguments will be passed through the url generator. -* `activeRouteKey` must be the route key name. +* `layout`: a custom layout for KNP Menu. +* `args`: an array of parameters that will be passed to the `MenuBuilder`. +* `activeRouteKey`: the route key name that should be marked as active. - The argument `activeRouteKey` may be a twig variable, defined elsewhere in your template, even in child templates. +## Building a menu -## Create an entry in an existing menu +To build a menu, you must create a class that implements `\Chill\MainBundle\Routing\LocalMenuBuilderInterface`. -If a route belongs to a menu, you simply add this to his definition in routing.yml : +### The `getMenuIds` method -```yaml - chill_person_history_list: - pattern: /person/{person_id}/history - defaults: { _controller: ChillPersonBundle:History:list } - options: - #declare menus - menus: - # the route should be in the 'person' menu : - person: - #and have those arguments : - order: 100 - label: menu.person.history +This static method returns an array of menu keys that this builder supports. For example, if you want to add items to the "person" menu: + +```php +public static function getMenuIds(): array +{ + return ['person']; +} ``` -* `order` (mandatory): the order in the menu. It is preferrable to increment by far more than 1. -* `label` (mandatory): a translatable string. -* `helper` (optional): a text to help people to understand what does the menu do. Not used in default implementation. -* `condition` (optional): an `Expression Language `_ which will make the menu appears or not. Typically, it may be used to say "show this menu only if the person concerned is more than 18". **Not implemented yet**. -* `access` (optional): an Expression Language to evalute the possibility, for the user, to show this menu according to Access Control Model. **Not implemented yet.** +### The `buildMenu` method -You may add additional keys, but should not use the keys described above. +The `buildMenu` method is called when a menu with one of the supported keys is rendered. -You may add the same route to multiple menus : - -```yaml - chill_person_history_list: - pattern: /person/{person_id}/history - defaults: { _controller: ChillPersonBundle:History:list } - options: - menus: - menu1: - order: 100 - label: menu.person.history - menu2: - order: 100 - label: another.label +```php +public function buildMenu($menuId, MenuItem $menu, array $parameters): void +{ + // ... +} ``` -## Customize menu rendering +* `$menuId`: the key of the menu being built (e.g., 'person'). +* `$menu`: the KNP Menu item representing the parent menu. +* `$parameters`: the arguments passed from the `chill_menu` call in the template (the `args` key). -You may customize menu rendering by using the `layout` option. +#### Example +```php +public function buildMenu($menuId, MenuItem $menu, array $parameters): void +{ + /** @var \Chill\PersonBundle\Entity\Person $person */ + $person = $parameters['person']; - TODO: this part should be written. + $menu->addChild('My Menu Entry', [ + 'route' => 'my_route_name', + 'routeParameters' => [ + 'id' => $person->getId(), + ], + ]) + ->setExtras([ + 'order' => 100, + ]); +} +``` -## Caveats +### Ordering items -Currently, you may pass arguments globally to each menu, and they will be all passed to route url. This means that : +You can order menu items using the `order` extra. In case of duplicate orders, the entry is kept, but the order between items with the same weight is random. -* the argument name in the route entry must match the argument key in the menu declaration in the twig template -* if an argument is missing to generate an url, the url generator will throw a `Symfony\Component\Routing\Exception\MissingMandatoryParametersException` -* if the argument name is not declared in route entry, it will be added to the url, (example: `/my/route?additional=foo`) +```php +$menu->addChild('Ordered Item', [/* ... */]) + ->setExtras(['order' => 50]); +``` + +### Adding a counter + +You can add a counter to a menu item by setting the `counter` extra: + +```php +$menu->addChild('Tickets', [/* ... */]) + ->setExtras([ + 'counter' => $this->ticketRepository->countOpenedByPerson($person), + 'order' => 150 + ]); +``` + +### Adding an icon + +You can add an icon to a menu item by setting the `icon` extra. The icon name corresponds to a [Fork Awesome](https://forkaweso.me/Fork-Awesome/icons/) icon name (without the `fa-` prefix). + +```php +$menu->addChild('My tasks', [ + 'route' => 'chill_task_singletask_my_tasks', +]) +->setExtras([ + 'order' => -10, + 'icon' => 'tasks', +]); +``` + +Currently, icons are extracted from Fork Awesome, but this might change in the future. + +## Existing Menus + +Here are some common menus used in Chill and the parameters they receive: + +* `person`: Parameter `person` (instance of `Chill\PersonBundle\Entity\Person`). Used in the person file. +* `accompanyingCourse`: Parameter `accompanyingCourse` (instance of `Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriod`). Used in the accompanying course file. +* `admin`: The main administration menu. +* `section`: The "sections" menu (top navigation). +* `user`: The "my menu" (user profile/actions). +* `household`: Parameter `household` (instance of `Chill\PersonBundle\Entity\Household\Household`). Used in the household file. + +## Good Examples + +For more complex implementations, you can refer to: + +* `src/Bundle/ChillTicketBundle/src/Menu/PersonMenuBuilder.php` +* `src/Bundle/ChillTicketBundle/src/Menu/SectionMenuBuilder.php` +* `src/Bundle/ChillDocGeneratorBundle/Menu/AdminMenuBuilder.php` +* `src/Bundle/ChillDocStoreBundle/Menu/MenuBuilder.php` +* `src/Bundle/ChillPersonBundle/Menu/UserMenuBuilder.php` +* `src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php`