Routing and menus¶
The Chill’s architecture allows to choose bundle on each installation. This may lead to a huge diversity of installations, and a the developper challenge is to make his code working with all those possibles installations.
Chill uses menus to let users access easily to the most used functionalities. For instance, when you land on a “Person” page, you may access directly to his activities, notes, documents, … in a single click on a side menu.
For a developer, it is easy to extend this menu with his own entries.
See also
- Symfony documentation about routing
- This documentation should be read before diving into those lines
- Routes dans Chill (FR)
- The issue where we discussed routes. In French.
Create routes¶
Note
We recommand using yaml to define routes. We have not tested the existing other ways to create routes (annotations, …). Help wanted.
The first step is as easy as create a route in symfony, and add some options in his description :
chill_main_dummy_0:
pattern: /dummy/{personId}
defaults: { _controller: CLChillMainBundle:Default:index }
options:
#we begin menu information here :
menus:
foo: #must appears in menu named 'foo'
order: 500 #the order will be '500'
label: foolabel #the label shown on menu. Will be translated
otherkey: othervalue #you may add other informations, as needed by your layout
bar: #must also appears in menu named 'bar'
order: 500
label: barlabel
The mandatory parameters under the menus definition are :
- name: the menu’s name, defined as an key for the following entries
- order. Note: if we have duplicate order’s values, the order will be incremented. We recommand using big intervals within orders and publishing the orders in your documentation
- label: the text which will be rendered inside the <a> tag. The label should be processed trough the trans filter ({{ route.label|trans }})
You may also add other keys, which will be used optionally in the way the menu is rendered. See
Warning
Although all keys will be kept from your yaml definition to your menu template, we recommend not using those keys, which are reserved for a future implementations of Chill :
- helper, a text to help user or add more informations to him
- access : which will run a test with Expression Langage to determine if the user has the ACL to show the menu entry ;
- condition, which will test with the menu context if the entry must appears
Show menu in twig templates¶
To show our previous menu in the twig template, we invoke the chill_menu function. This will render the foo menu :
{{ chill_menu('foo') }}
Passing variables¶
If your routes need arguments, i.e. an entity id, you should pass the as argument to the chill_menu function. If your route’s pattern is /person/{personId}, your code become :
{{ chill_menu('foo', { 'args' : { 'personId' : person.id } } ) }}
Of course, person is a variable you must define in your code, which should have an id accessible property (i.e. : $person->getId()).
Note
Be aware that your arguments will be passed to all routes in a menu. If a route does not require personId in his pattern, the route will become /pattern?personId=XYZ. This should not cause problem in your application.
Warning
It is a good idea to reuse the same parameter’s name in your pattern, to avoid collision. Prefer /person/{personId} to /person/{id}.
If you don’t do that and another developer create a bundle with person/{personId}/{id} where {id} is the key for something else, this will cause a lot of trouble…
Rendering active entry¶
Now, you want to render differently the active route of the menu [1]. You should, in your controller or template, add the active route in your menu :
{{ chill_menu('foo', { 'activeRouteKey' : 'chill_main_dummy_0' } ) }}
On menu creation, the route wich has the key chill_main_dummy_0 will be rendered on a different manner.
Define your own template¶
By default, the menu is rendered with the default template, which is a simple ul list. You may create your own templates :
#MyBundle/Resources/views/Menu/MyMenu.html.twig
<ul class="myMenu">
{% for route in routes %}
<li><a href="{{ path(route.key, args ) }}" class="{%- if activeRouteKey == route.key -%}active{%- endif -%}">{{ route.label|trans }}</a></li>
{% endfor %}
</ul>
Arguments available in your template :
- The args value are the value passed in the ‘args’ arguments requested by the chill_menu function.
- activeRouteKey is the key of the currently active route.
- routes is an array of routes. The array has this structure: routes[order] = { ‘key’ : ‘the_route_key’, ‘label’ : ‘the route label’ } The order is resolved: in case of collision (two routes from different bundles having the same order), the order will be incremented. You may find in the array your own keys ({ ‘otherkey’ : ‘othervalue’} in the example above).
Then, you will call your own template with the layout argument :
{{ chill_menu('foo', { 'layout' : 'MyBundle:Menu:MyMenu.html.twig' } ) }}
Note
Take care of specifying the absolute path to layout in the function.
Footnotes
[1] | In the default template, the currently active entry will be rendered with an “active” class : <li class=”active”> … </li> |