How to show only populated menu tabs in Drupal?
In evaluating the Invite and Support modules for Drupal recently, we realized the default tab navigation is not the most user friendly. In particular, each module has a page of tabs that show the various categories of invitations or support tickets (pending, cancelled, etc). For developers, it开发者_StackOverflow's easiest to pre-define all the tabs, but from a user standpoint, it makes more sense to only be offered the tabs that contain content.
I assume it's possible to run queries to check which tabs should be displayed for a particular user and change the menus using hook_menu_alter. However, is that the best way to do it or will that cause problems with Drupal's menu caching? Is there a better way?
The answer by jhedstrom is correct, but I'm not that convinced that dynamically showing/hiding local tasks results in better UX, that sounds kinda confusing to me.
Instead, my suggestion would be to use a title callback (which can be added with the same hook_menu_alter() and show the number of things inside that specific tab. That is what I for example use for Privatemsg to show the number of unread messages.
See privatemsg_title_callback() for an example and hook_menu for more information about title callbacks in general.
If you want to selectively remove tabs in a dynamic way (eg, one node gets a tab, while another does not), you won't be able to use hook_menu_alter() because that only has an effect when the menu cache is being built. However, you can do this by overriding the menu access callback. If access to a tab is denied, it won't be displayed.
For example, to override a node tab, you might do something like this:
function mymodule_menu_alter(&$items) {
$item['node/%node/foo']['access callback'] = 'mymodule_override_access';
}
function mymodule_override_access($node) {
// Perform queries, logic, etc to determine if content exists at node/nid/foo.
// Return false if there is no content, otherwise fall through to the original
// access callback function.
}
精彩评论