By now you’ve got an awesome Acl and Auth controlled app running. However, making navigation menus is a pain with dynamic, and variable permissions. Outside of making menu elements for each type of Aro and including them in your layout, there currently aren’t many options (at least none that I’m aware of). I was faced with this exact problem a while back, and couldn’t find a suitable solution, so I made one. I called it the
What does it do?
This menu component will scan through your application, and generate a list of menu-able actions to be used in menus. When a request is made for a
MenuComponent using page, a nested menu array will be created based on the current User’s access permissions. This menu is set to the
View and available in your layouts / views. To top it all off, this is done automagically!
What doesn’t it do?
It doesn’t kill the performance of your site for one. It uses a lot of caching to help minimize the hit your application will endure when using dynamically generated menus. It also doesn’t generate menu items for actions that involve id’s, or information from the session. These can be added into the menu’s structure, but it is not done automatically. It also doesn’t make any HTML, how you render these menus is totally up to you.
How do I use it?
At its most basic use, download the
MenuComponent and test case and add them to your app. Include the
MenuComponent in your
AppController or wherever you want to use it and you’re ready to go.
- var $components = array('Acl', 'Auth', 'Menu');
It can obviously get far more complicated.
MenuComponent has a number of settings that can be set using “alternate component declarations”/posts/view/cakephp-easter-eggs . Any of the class variables can be set in this manner. Additional configuration related to specific controllers is done in the respective controller. This seems a bit odd, but I chose to do it this way, as it keeps each controller’s contribution to the menu inside that controller. This is in contrast to setting every option for every controller in
AppController or wherever you are including the
MenuComponent. As this would end up bloated and ugly very quickly.
Using controller options for the MenuComponent
Controller options for the
MenuComponent control how the menu is generated for that controller, and nothing else. Each controller’s menuOptions are separate and affect nothing outside of its own actions. $meunOptions provide facilities for aliasing actions, excluding actions and setting the parent menu item of the controllers actions.
Renaming action titles in the menus
Often you don’t want the action name to be the display title in your menu. Setting an alias lets you control the menu’s title.Show Plain Text
You basically map the action name to the title text you want to display. Pretty straightforward, right now due to the way the caching is done, you would have to do any i18n work in the views.
Excluding actions from the menu
Excluding actions is done by creating an array of non-private actions, you want to exclude from the menus. You don’t need to specify the following either ‘view’, ‘edit’, ‘delete’, ‘admin_edit’, ‘admin_delete’, ‘admin_edit’, or ‘admin_view’. If you want to change the global list of excluded actions modify
MenuComponent::excludeActions. You can also set
exclude to ‘‘. Setting exclude to ‘‘ will remove an entire controller, and all of its actions from the generated menus.
Changing the parent element
You can also set the parent menu element for all actions in a controller. This lets you nest a set of controller/actions under an artificial or generated menu.Show Plain Text
- 'parent' => 'my-menu-item'
This would place all the menus generated for this controller under the menu element with an id of ‘my-menu-item’. Using parent gives you a powerful, and easy way to create a hierarchy in your application’s menu without affecting the actual structure of the application. Menu ids are generated automatically and take the form of
Removing the controller element
There are times when you don’t want a menu element for the controller. Normally these occur when using manually added menu elements or specifying
$menuOptions['parent'] in these circumstances you can:
- 'controllerButton' => false,
This will remove the controller button, and all the actions will become children of whatever
$menuOptions['parent'] is set to.
Manually creating menu elements
In addition to automagic generation of menu elements you can manually create menu elements. I’ve used this when, I want to promote a single action to somewhere it normally wouldn’t be able to get to in the menu structure. Or to create menu elements for actions that need an id parameter to work. Creating menu elements looks a bit like this.Show Plain Text
addMenu() you can create menu elements for any path or url on your application. However, the big catch is that all your
addMenu() calls must occur before the menus are constructed. This normally occurs automatcally in
startup() but can be manually controlled. See the doc blocks for more information regarding that. It is also important to note that if two menu elements exist for the same id, and a user has access to both only the first will show up in the final menu.
Well I hope you find this Component useful and I’d love to hear on how to improve it. You can download the menu component and its related test from my gitHub repository