2

What is the correct way of using hook_menu_later.

I did this in my module to redirect (see also redirect in hook_init makes body text disappear):

function MYMODULE_menu_alter(&$items) {
  $items['node/%node']['page callback'] = 'citykidz_node_page_view';
}

function MYMODULE_node_page_view($node) {
  if ($node->type == 'event') {
    if ($items = field_get_items('node', $node, 'field_event_date')) {
      $date = date_create($items[0]['value']);
      drupal_goto('news/events/day/' . date_format($date, 'Y-m-d'));
    }
  }
  else {
    return node_page_view($node);
  }
}

And this got me wondering: what if other modules are also overriding hook_menu_alter and setting their own page callbacks on 'node/%node'? Or even on access or whatever. This is the standard Drupal way of doing things, but surely it will lead to problems (that can be hard to detect). I see there is a module Chain Menu Access API that addresses this. Has anyone had success using this module? And has this issue been addressed in Drupal 8?

1 Answer 1

3

If two modules are altering the same menu item / form / page etc, last one will "win".

If you need some control over this, and are expecting collisions, you need to implement hook_module_implements_alter:

This hook is invoked during module_implements(). A module may implement this hook in order to reorder the implementing modules, which are otherwise ordered by the module's system weight.

Do your best to have your hook fire last, and if menu item you are altering does not look like the one you are expecting (it was altered already), write a warning message to watchdog.

10
  • That is excellent advice, especially in the case of a page callback where I want my module's code to run. But could it be possible that correct execution of the code depends on multiple module's code to run, especially in the case of the 'access callback'? Aug 7, 2014 at 9:02
  • @J.Reynolds Access callbacks are different, they are not altering single object, they are just adding "yes / no / no change" entries to access array. They are designed to be used by many modules simultaneously, so should not create any problems.
    – Mołot
    Aug 7, 2014 at 9:11
  • Other modules can also execute hook_module_implements_alter() and put their hook_menu_alter on top ;)
    – milkovsky
    Aug 7, 2014 at 10:15
  • @milkovsky yes, they can. As usual, simple solution is not to install two conflicting software (here: modules) on one system.
    – Mołot
    Aug 7, 2014 at 10:30
  • After thinking about it some more I am finding myself unconvinced. What if I install Revisioning module and my own module. My module runs later than Revisioning. I implement hook_menu_alter for nodes at revision edit path (node/%/revision/%/edit I think). I only want to allow person to edit revision if he has certain userpoints. Must I now re-implement Revisioning's complex set of permissions also? I must return either TRUE or FALSE. Hence I will have to chain onto Revisioning's own access calback, and if it return TRUE then do I do my own module's check on top of that. Aug 7, 2014 at 11:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.