I want my module to override the path was set by another module
Example:
Module A has register a path:
$menu['node/%id/test'] = array(
'title' => 'Test',
'page callback' => 'test_A',
'page arguments' => array(1),
'access callback' => 'test_access',
'access arguments' => array(1),
'type' => MENU_LOCAL_TASK,
)
Now I create module B and register the same path.
$menu['node/%id/test'] = array(
'title' => 'Test',
'page callback' => 'test_B',
'page arguments' => array(1),
'access callback' => 'test_access',
'access arguments' => array(1),
'type' => MENU_LOCAL_TASK,
)
Every request to this path
www.mysite.com/node/1/test
will route to module B not A.
What is the best way to override an existing path was set by other module?
You want to use an alter hook, hook_menu_alter():
function mymodule_menu_alter(&$items) {
$items['node/%id/test']['page callback'] = 'test_B';
}
Since you're just modifying an existing menu router definition, you only need to declare the part you want to change (e.g., the page callback function name). Note also $items is passed by reference, so you don't need to return anything.
Related
I have simple module:
function cabinet_menu() {
$items['cabinet'] = array(
'title' => 'cabinet',
'title callback' => 'cabinet_title',
//'title arguments' => array(1),
'page arguments' => array('cabinet_mysettings'),
'page callback' => 'cabinet_page',
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
I want to pass to 'page arguments' a function called 'cabinet_mysettings'
function cabinet_mysettings() {
debug('call settings');
global $user;
$cabinet = user_load($user->uid);
return $cabinet;
}
function cabinet_page($cabinet) {
debug($cabinet);
}
In 'cabinet_page' debug shows only string "cabinet_mysettings".
Why does the menu hook not understand that the page arguments is not a function name but a sting?
UPD: devel module hook_menu:
$items['devel/reinstall'] = array(
'title' => 'Reinstall modules',
'page callback' => 'drupal_get_form',
'page arguments' => array('devel_reinstall'),
'description' => 'Run hook_uninstall() and then hook_install() for a given module.',
'access arguments' => array('access devel information'),
'file' => 'devel.pages.inc',
'menu_name' => 'devel',
);
I think that 'devel_reinstall' is a function.
Does anyone know how such callbacks work?
Page arguments are not designed to do something behind the scenes. You use them to pass arguments to page callback by putting them in the url.
Putting string in page arguments as you did ('page arguments' => array('cabinet_mysettings')) causes that only that string is passed. There is no way around this. Refer to hook_menu documentation for more comprehensive explanation.
Therefore, in your case I would consider something like this:
function cabinet_menu() {
$items['cabinet/%'] = array(
'title' => 'cabinet',
'title callback' => 'cabinet_title',
'page arguments' => array(1),
'page callback' => 'cabinet_page',
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function cabinet_mysettings() {
debug('call settings');
global $user;
$cabinet = user_load($user->uid);
return $cabinet;
}
function cabinet_page($my_param_name) {
$cabinet = cabinet_mysettings($my_param_name);
debug($cabinet);
}
Does this help?
For my drupal website, in my custom module (hr_payroll.module) I have the following to add URL handlers:
function hr_payroll_menu() {
$items['hr/payroll/employee/hours/overtime'] = array(
'title' => 'Overtime Submission',
'page callback' => 'hr_payroll_page',
'page arguments' => array('employee','hours','overtime'),
'access arguments' => array('access hr payroll'),
'type' => MENU_CALLBACK,
);
$items['hr/payroll'] = array(
'title' => 'Payroll',
'page callback' => 'hr_payroll_intro',
'access arguments' => array('access hr payroll'),
'type' => MENU_CALLBACK,
);
return $items;
}
On my site is a block that simply contains
echo(drupal_get_title());
If I go the URL hr/payroll, it shows the title 'Payroll'
BUT if I go to the URL hr/payroll/employee/hours/overtime it still shows 'Payroll' instead of the expected 'Overtime Submission'
So what am I totally misunderstanding about how the $title element of the menu item or the function drupal_get_title() work?
I believe you are using the hook_menu in the wrong way based on what you want to do.
First menu
$items['hr/payroll/employee/hours/overtime'] = array(
'title' => 'Overtime Submission',
'page callback' => 'hr_payroll_page',
'page arguments' => array('employee','hours','overtime'),
'access arguments' => array('access hr payroll'),
'type' => MENU_CALLBACK,
);
Are the arguments 'employee' 'hours' 'overtime' are static or they are dynamic ?? , and I see that page arguments supplied are the same ('employee','hours','overtime')
If they are dynamic use wildcard instead like
$items['hr/payroll/%/%/%'] = array(
'title' => 'Overtime Submission',
'page callback' => 'hr_payroll_page',
'page arguments' => array(2,3,4),
'access arguments' => array('access hr payroll'),
'type' => MENU_CALLBACK,
);
If the menu link "hr/payroll/employee/hours/overtime" is static , that means you don't need the access arguments provided as u already know what these values are on your page callback function.
And also why are you using type as MENU_CALLBACK.Is that by reason or by just random??
I am trying to create a very simple page in my module using hook_menu(), but after I test it I get, "You are not authorized to access this page". I can't figure out what I am doing wrong. Following is the code that I used.
Note that I created this module under the existing module package. For instance the module folder is xyz and I created a folder as xyz_mobile for the module, and I added xyz in the info as the package. I don't know if that would have anything to do with it.
function xyz_mobile_menu() {
$items['mobile'] = array(
'title' => 'page test',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
I'm assuming Drupal 6 here. You need the 'access arguments' and 'page callback' elements in your $items array:
function mymodule_menu() {
$items = array();
$items['mobile'] = array(
'title' => 'page test',
'page callback' => 'mymodule_my_function',
'access callback' => 'user_access',
'access arguments' => array('access content'), // or another permission
'type' => MENU_CALLBACK,
);
return $items;
}
The 'access callback' element contains the name of the function (in this case, user_access) that will check if the user has the permission specified in the 'access arguments' element.
The 'page callback' element will run your custom function.
function mymodule_my_function() {
return 'this is the test page';
}
Lastly, don't forget to clear the menu cache before you re-test.
How can I add a tab into my personal profile (/users/my-name)?
I used this function, but nothuing shows up:
function tpzclassified_menu() {
$items['user/%user/kleinanzeigen'] = array(
'title' => t('Meine Kleinanzeigen'),
'page arguments' => array(1),
'access callback' => TRUE,
'type' => MENU_LOCAL_TASK,
);
return $items;
}
You're missing the page callback property:
function tpzclassified_menu() {
$items['user/%user/kleinanzeigen'] = array(
'title' => t('Meine Kleinanzeigen'),
'page callback' => 'tpzclassified_kleinanzeigen',
'page arguments' => array(1),
'access callback' => 'user_view_access',
'access arguments' => array(1),
'type' => MENU_LOCAL_TASK,
);
return $items;
}
function tpzclassified_kleinanzeigen($account) {
return 'This is the Meine Kleinanzeigen page';
}
Replace tpzclassified_kleinanzeigen with the function name that generates the page.
Also, never use 'access callback' => TRUE: it's a huge security hole. I've changed that to use user_view_access(), which checks to the see if the user is allowed to view %user's profile. You could use user_edit_access() if you wanted to check to see if a user is allowed to edit %user's profile.
I upgraded a module from 5 to 6. I only have one problem:
I can access the settings page for it, but can not see the contents of it.
This is my code:
function agbnagscreen_menu() {
global $user;
$items = array();
if (agbnagscreen_nag($user)) {
// var_dump($_GET['q']); die();
drupal_goto(sprintf('%s/%s', AGBNAGSCREEN_NAGURL, base64_encode($_GET['q'])));
die();
}
$items['admin/settings/agbnagscreen'] = array(
// 'path' => 'admin/settings/agbnagscreen',
'title' => 'AGB nagscreen',
'access callback' => user_access('Einstellungen von AGB aendern'),
//'access' => user_access('Einstellungen von AGB aendern'),
'page callback' => 'drupal_get_form',
'callback arguments' => array('agbnagscreen_settings_fapi'),
);
$items[AGBNAGSCREEN_NAGURL] = array(
// 'path' => AGBNAGSCREEN_NAGURL,
'title' => 'Allgemeine Geschaeftsbedingungen',
'access' => TRUE,
'callback' => 'drupal_get_form',
'callback arguments' => array('agbnagscreen_fapi'),
'type' => MENU_SUGGESTED_ITEM,
);
return $items;
}
I think the problem is cause by this line:
'page callback' => 'drupal_get_form',
Is that correct? How can I write it, that it works?
You might want to read through the Drupal menu system (Drupal 6.x) handbook page to understand the changes to the menu system: you have several problems in your hook_menu implementation.
The conditional at the top will never fire: Drupal 6 only calls hook_menu() when the menu is rebuilt, not on every page load.
There is no callback: use page callback.
The page callback accepts page arguments, not callback arguments.
There is access: use access callback.
access callback always a string containing the function name, not a function, and defaults to "user_access": you need to supply access arguments.
A modified version of your hook_menu implementation might be:
function agbnagscreen_menu() {
$items = array();
$items['admin/settings/agbnagscreen'] = array(
'title' => 'AGB nagscreen',
'access arguments' => array('Einstellungen von AGB aendern'),
'page callback' => 'drupal_get_form',
'page arguments' => array('agbnagscreen_settings_fapi'),
);
$items[AGBNAGSCREEN_NAGURL] = array(
'title' => 'Allgemeine Geschaeftsbedingungen',
'access arguments' => array('access content'),
'page callback' => 'drupal_get_form',
'page arguments' => array('agbnagscreen_fapi'),
'type' => MENU_SUGGESTED_ITEM,
);
return $items;
}