In a custom module I'm implementing the hook_menu_alter hook to alter the page callback for the $menu['taxonomy/term/%taxonomy_term'] menu.

I've noticed that my hook is not implemented because another contrib module ( Taxonomy Display module ) already implements the same hook (all works fine if I disable TD).

What I need is not to prevail on TD hook with mine, but to use my hook under a certain condition, and TD hook for all other cases.

The condition is the presence of parameter "v" in the querystring, like the following example:

if url == taxonomy/term/tid?v=value then use mymodule_menu_alter

if url == taxonomy/term/tid then use taxonomy_display_menu_alter

How I can do that?

Thank you very much!


  • Your hook should be called even if it's implemented in the Taxonomy Display Module Nov 21, 2011 at 21:25

3 Answers 3


If you implement a hook, it will always be executed.

The condition of a query string makes things more complicated in your situation, because all menu items are defined by their path (taxonomy/term/tid in your case). This means that - as far as Drupal is concerned - taxonomy/term/tid?v=value and taxonomy/term/tid have the same menu item, so both requests will be handled by the same code.

Is it really necessary that the URL takes the form of ?v=value? If you could make it taxonomy/term/tid/value, you can create your own custom menu item for taxonomy/term/%/%, and simply leave the taxonomy/term/tid path as is.

  • If that is not possible, you need to make sure that your hook is called after the other one (using module weight or hook_module_implements_alter()). Then, look if the argument is there, do your own stuff and if not, manually pass the call forward by calling the Taxonomy Display page callback in your code().
    – Berdir
    Nov 22, 2011 at 6:59
  • I'm not sure if it would work to use hook_module_implements_alter, because hook_menu is called when the menu cache is built, not at every request, so you cannot use it to switch the menu callback on a per-request basis. (Or am I wrong?) Nov 22, 2011 at 8:38
  • @Berdir: yes! it is exactly what i did!
    – MXT
    Nov 22, 2011 at 9:03
  • marcvangend: Of course, it's not possible to use module_implements_alter() on a per request basis (the hook call itself is cached as well). But it can be used as an alternative to changing the menu weight, which is not always an option. E.g. when you need to be before a module in one case but later for another hook.
    – Berdir
    Nov 22, 2011 at 10:28

I'm not sure but perhaps you should make the weight of your module higher than Taxonomy Displays, so your modules hook get called first. Check out this http://drupal.org/node/110238


I've reached a working solution:

function mymodule_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'menu_alter') {
    // move mymodule at the end of the list, so it will be implemented at last: 
    $group = $implementations['mymodule'];
    $implementations['mymodule'] = $group;

function mymodule_menu_alter(&$menu) {
  if (isset($menu['taxonomy/term/%taxonomy_term'])) {
    // alter menu to serve my own custom term page
    $menu['taxonomy/term/%taxonomy_term']['page callback'] = 'mymodule_term_page';

function mymodule_term_page($term) {

    $params = drupal_get_query_parameters();
    $vocab = taxonomy_vocabulary_load($term->vid);

    // If this voc hasn't to be processed, return the default taxonomy term page:
    if(!variable_get('mymodule_' . $vocab->machine_name . '_enabled')) {
      module_load_include('inc', 'taxonomy', 'taxonomy.pages');
      return taxonomy_term_page($term);

    // If param 'v' is present in querystring
    if(isset($params['v'])) {
      // return another custom callback term page:
      return mymodule_show_term_tree($term);
    else {
      // Else call Taxonomy Display module calback page:
      module_load_include('module', 'taxonomy_display');
      return taxonomy_display_taxonomy_term_page($term);

I'll hope this will be usefull to others.

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.