I was watching the development videos (Video: Developing farmOS) and it was mentioned briefly at the end of the first one that it is possible to have a page appear as a tab (i.e. alongside “Dashboard”, “Quick forms” and “Reports”). Is there a short example to work from or some documentation that would help me get started with adding such a tab for a custom module? Any pointers or nudges in the right direction would be appreciated. Thanks.
I think I figured this out… If it is of interest to anyone later the key insights were:
- Use the
farm/reports
andfarm/quick
modules as a guide. - In
hook_menu
use:$items['farm/tabs'] = ...
wheretabs
is the name that appears in the URL. - Changes to the
hook_menu
method appear to require a module off/on cycle to take effect. - Changes to the
page callback
method are live and do not require a module off/on cycle.
Here is a minimum implementation of a new tab with 2 sub-tabs that can appear in the www/sites/all/modules/
directory.
<?php
/**
* @file
* Tab Test module.
*/
function tab_test_permission() {
return array(
'view tab test' => array(
'title' => t('View tab_test'),
),
'configure tab test' => array(
'title' => t('Configure tab_test'),
),
);
}
function tab_test_farm_access_perms($role) {
$perms = array();
// Load the list of farm roles.
$roles = farm_access_roles();
// If this role has 'edit' access, allow them to see these tabs.
if (!empty($roles[$role]['access']['edit'])) {
$perms[] = 'view tab test';
}
// If this role has 'config' access, allow them to also configure tab test.
if (!empty($roles[$role]['access']['config'])) {
$perms[] = 'configure tab test';
}
return $perms;
}
/**
* Implements hook_menu().
*/
function tab_test_menu() {
$items = array();
$items['farm/tabs'] = array(
'title' => 'Tabs',
'page callback' => 'tab_test_view',
'access arguments' => array('view tab test'),
'type' => MENU_LOCAL_TASK,
);
$items['farm/tabs/info'] = array(
'title' => 'Info',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -100,
);
$items['farm/tabs/info2'] = array(
'title' => 'Info2',
'type' => MENU_LOCAL_TASK,
'page callback' => 'tab_test_view2',
'access arguments' => array('view tab test'),
'weight' => 100,
);
return $items;
};
// Changes to the callback functions below are live.
// The function for the callback set above requires a module off/on cycle.
function tab_test_view() {
return t('Select a tab from the menu above.');
};
function tab_test_view2() {
return t('Some different other stuff.');
};
Hi @braught - welcome to the farmOS forum!
Sounds like you figured it out. Well done!
For future reference, the documentation for Drupal 7’s hook_menu()
is available here: https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_menu/7.x
Changes to the
hook_menu
method appear to require a module off/on cycle to take effect.
The menu router item information is only read when Drupal has reason to believe changes have been made to it, and are then stored in the {menu_router}
table for faster lookups. Enabling modules triggers this, as you noticed. You can also simply submit the modules form (/admin/module) without turning any off/on to achieve the same affect. Alternatively, if you have Drush installed, you can run drush cc menu
.
Note: this all changes in Drupal 9 / farmOS 2.x (in active development), but the concepts are mostly the same. This might help when it comes time to upgrade: https://www.lullabot.com/articles/what-happened-to-hook_menu-in-drupal-8
Hope that helps! Thanks for sharing your lessons with the community!