If you are developing a module for Drupal you might need to use tabs to simplify a bit a screen which has too much functionality. Typically a settings page that might need too many options to comfortably fit on a single screen. Since I had to search and experiment a bit to find out how to do it I decided to write a short post with my findings. In this article I assume you have a basic understanding on writing Drupal modules.
Basically you define what content goes in what tab in your modules hook_menu() function defining menu items which are called MENU_LOCAL_TASK. Suppose I want a page which has two tabs: Company and Mail as seen on the screen shot. This is the corresponding hook_menu() code:
* Implementation of hook_menu()
*/
function my_module_menu() {
$items = array();
// definition for main page
$items[‘settings’] =
array(
‘title’ => t(‘Settings’),
‘description’ => t(‘Settings for Ticket System’),
‘page callback’ => ‘my_module_settings_root’,
‘access callback’ => true,
);
// definition for default tab.
$items[‘settings/company’] =
array(
‘title’ => t(‘Company’),
‘description’ => t(‘Settings for Ticket System’),
‘type’ => MENU_DEFAULT_LOCAL_TASK,
‘weight’ => 0,
);
// definition for additional tab.
$items[‘settings/mail’] =
array(
‘title’ => t(‘Mail’),
‘description’ => t(‘Settings for Ticket System’),
‘access callback’ => true,
‘page callback’ => ‘my_module_settings_mail’,
‘type’ => MENU_LOCAL_TASK,
‘weight’ => 2,
);
return $items;
}
function my_module_settings_root() {
return ‘page root’;
}
function my_module_settings_mail() {
return ‘page mail’;
}
Here are the main highlights of how this works:
- The first item should be a standard menu item and its route should be shared with the other tabs. In this case, the route is ‘settings’.
- Each additional tab should be of type MENU_LOCAL_TASK.
- You need at least two tabs. If you only have one child route then you will not see a tab.
- If you add more than one MENU_LOCAL_TASK, you must single out one as required by setting its type to MENU_DEFAULT_LOCAL_TASK. The default local task doesn’t need a ‘page callback’ since it is handled by the root item.
- Additional tabs should be of type MENU_LOCAL_TASK and should have a page callback function assigned to them.
- The ‘title’ of the standard item appears a the top of the tab bar. The title of the MENU_LOCAL_TASK and MENU_DEFAULT_LOCAL_TASK are used as the titles on the individual tabs.
- You can change the order of the tabs by adding a ‘weight’ item to each menu
item. - You need to specify an ‘access callback’ item and have permissions to view the corresponding tab.
Finally, remember that each time you change an item in hook_menu() you need to flush your cache so that the items are re-read. This can be achived by going to admin->settings->performance and hitting clear cache or by using drush and doing ‘drush cache clear’.


First up, great post! I’ve got a big question nagging me, I really enjoy the design of your website and tried to install the same theme on my WP website. Stil, there is some kind of strange coding error in the footer. Do you have any tips, which settings are you using? Please PM me on Twitter @FitnessHealthGuide or per e-mail.