Add a views display as a tab to a forum listing.
I've been building the community pages for a client's site where one of the most popular areas is the forum. The design called for the forum listing to be the default menu tab with a second tab for searching the forum. I wanted to use a view with an exposed filter to search the site index and limit the results to this specific forum.
In Drupalese the default tab is the MENU_DEFAULT_LOCAL_TASK in the menu definition, and any additional tabs are MENU_LOCAL_TASK(s).
The best way to see how tabs work is to look at the core node module. The default tab is the node "view", but you only see that tab if you also can see the "edit" tab or any other tabs that you have access to. These other tabs are the local tasks. Node sets this up in hook_menu() by making the "view" not only a MENU_DEFAULT_LOCAL_TASK, but also a MENU_NORMAL_ITEM , which is how a "normal" page is indicated in drupal's menu system. The "edit" tab is a MENU_LOCAL_TASK.
The problem with tabs and the forum module
The forum module uses a heirarchical taxonomy to categorize forum containers, forums and forum topics. Let's ignore forum containers. When you navigate to a forum (say example.com/forum/11) you're really trying to navigate to a taxonomy term page. But taxonomy offers a hook, hook_term_path() that lets other modules take over that navigation. Forum uses this hook direct the term's path to a path created by forum's hook_menu() implementation, which then returns a listing of topics (topics are nodes, but that's not important here).
The point is that the forum listing page isn't a MENU_NORMAL_ITEM, it's a MENU_SUGGESTED_ITEM . This means (as far as I can tell) that the menu path is all ready to go, but only after you've created a forum (remember, it's really just a taxonomy term). And, there is no defaut local task defined. The bottom line is that now we can't simply give a views tab display the path forum/11/search and expect the tab to show up. First we need to alter the forum module's menu.
This all goes in a custom module, here named custom_forum.
<?php
/*
* Implementations of hook_menu_alter().
*/
function custom_forum_menu_alter(&$items) {
$items['forum/11'] = array(
'page callback' => 'forum_page',
'page arguments' => array(1),
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
'module' => 'forum',
'file' => 'forum.pages.inc',
);
$items['forum/11/view'] = array(
'title' => 'Forums',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10
);
}
?>You can see that first we duplicate the forum item and make it the MENU_NORMAL_ITEM, then add it again, just like in the node module, also making it a MENU_DEFAULT_LOCAL_TASK. The weight is set low so it's always on the left edge of the tabs.
Note that the forum ID (really a term ID in the forum vocabulary) is hard coded here. I could not get this work with wildcards, but I didn't need to for this site, which will only ever have a couple of forums. I bet wildcards could be made to work by first unsetting $items['forum'] in the hook_menu_alter().
Now, when the views display (as a menu normal tab) is added to the existing path forum/11/search, Drupal knows what to do, and both tabs appear. This all works great with path aliases too.
Another note: This client wanted to use the forumthread module, which makes Drupal forums look like it's 1995 instead of 2003. So instead of altering forum's menu, I altered forumthread's menu, but I did not show that here.

For wildcards to work you need to use the to_arg($arg) function.
So say your menu path was $items['forum/%mymenupath'] then you use the to_arg() to tell drupal what the wildcard actually is.
mymenupath_to_arg($arg){
return 11;
}
Obviously theres no point using a static string.
Post new comment