3

I'm building a module for which I want to create two dynamic menus: one main menu with each menu item being a group name that the user belongs to (the groups come from a different database) and a secondary menu with a fixed set of menu items that manipulate specific properties of the group selected in the main menu (for example show group members).

What would be a good approach to do this? I found this question that shows how to create a menu within a module, but I'm not sure how to tackle the dynamic part of the menu items. Each user can have a different main menu, depending on the groups the user is part of, and the secondary menu items need to pass the group id of the selected main menu item. Next to hook_menu, I suppose I need to do something with wildcards, but I've never worked with those in menus so I'm not sure.

I would like to be able to use the menus as a source for primary and secondary menus in different themes, so I'm flexible with changing the site appearance by selecting another theme. I'm using Drupal 7.

  • I found a way to do the first bit: create a dynamic primary menu. From what I have learned it seems menus in drupal are not meant to be dynamic; they are cached and after a change a menu_rebuild is required which is slow. I therefor create menu items for each group (and do a rebuild after a new one is added) and define an access callback that determines if a user is part of the group and may therefor see the menu item. Don't know how this will perform with thousands of groups though. – Whiskey Oct 24 '11 at 9:20
2

I found a way to do this, but I'm still interested to know if this is the right approach (and if bad things will happen with a very large number of groups and users).

Both menus are created using hook_enable in the install file of the module (the development module is an excellent example on how to do this).

Like I say in my comment, I don't think you can create dynamic menu items so I'm creating a menu item for each group (when a group is added, I need to do a menu_rebuild). To determine if the menu item should be visible for a user, I created an access callback that checks if a user is part of that group. This callback will be called with every page request, so it will always work.

The secondary menu works with a wildcard and a to_arg function. For example, a menu item is set as $items['pmenu/%get_groupid/grouppage'] and in the function get_groupid_to_arg($arg) I'm extracting the groupid from the path with arg(1), which is returned (for details see hook_menu and the Menu example). The secondary menu items also use the same access callback to check if the user may see the menu item.

Finally I had to apply a fix for the theme, because the corresponding primary or parent menu item (group) would not be set as active if a secondary menu item was selected. I'm using Marinelli and applied the patch in comment 14 of this issue. That didn't quite work, so I changed it a bit to only look at the path when checking for a parent as described in comment 16.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.