0

In hook_menu, I have

$path = "events"

$items[$path] = array(
  'title' => t('Events'),
  'page callback' => 'my_events_page',
  'access arguments' => array('view my events'),
  'type' => MENU_NORMAL_ITEM,
  'file' => 'my_events.pages.inc',
);

$items[$path . '/past'] = array(
  'title' => t('Past events'),
  'page callback' => 'my_events_past_page',
  'access arguments' => array('view my events'),
  'type' => MENU_NORMAL_ITEM,
  'file' => 'my_events.pages.inc',
);

$items[$path . '/%'] = array(
  'title' => t('Events'),
  'page callback' => 'my_events_page',
  'page arguments' => array($depth),
  'access arguments' => array('view my events'),
  'type' => MENU_CALLBACK,
  'file' => 'my_events.pages.inc',
);

They were working, but not now.

If I change $items['events/past'] to $items['events/past1'], it works.

Does it mean I have path conflict? If so, how can I resolve it?

Rows in my {menu_router} table are as follows:

path: events
page_callback: views_page (but I set it to xxx_events_page in hook_menu)
fit: 1
include_file: empty (should not be empty)
--
path: events/%
page_callback: xxx_events_page (good)
fit: 2
include_file: a file path is there
--
path: events/past
page_callback: views_page (but I set it to xxx_events_past_page in hook_menu)
fit: 3
include_file: empty (should not be empty)

If I update the page_callback and include_file it works. If I clear the cache, everything set back to default.

  • I took liberty to re-format your post and make it a consistent whole. Of course feel free to edit it again if you feel I missed something. – Mołot Sep 25 '13 at 12:04
  • Do you have any module that might define events path? See {menu_links} table, router_path and module columns. – Mołot Sep 25 '13 at 12:50
  • Solved. The issue is I defined the same path in views. I see a page_callback "views_page" in menu_router table, but I never understand what it means. (It gives me hint about view, but I never try to understand it.) – kenpeter Sep 26 '13 at 23:34
0

Assuming you are using Drupal 7:

Order matters only a bit - menu_router_build() saves all path into the {menu_router} table just the way they are set. But there are no guarantees database will return elements in that order. Logic to decide which menu item should be executed is in menu_get_item().

Actual query is:

$router_item = db_query_range('SELECT * FROM {menu_router} WHERE path IN (:ancestors) ORDER BY fit DESC', 0, 1, array(':ancestors' => $ancestors))->fetchAssoc();

As you can see, fitting elements are ordered by fit column, most specific first.

As you can see in actual _menu_router_build(), $fit gets initially set to 0 for each menu item:

foreach ($callbacks as $path => $item) {
  $load_functions = array();
  $to_arg_functions = array();
  $fit = 0;

It means it shouldn't be possible for the order of menu elements in hook_menu() to affect order of routing. Actual code is a bit complicated to understand, but elements specific should have higher fit than elements with '%' in them. As the comment in code says: // If there is no %, it fits maximally.

0

I use this code bellow in a custom module "mymodule" with drupal 7 and everthing work well. What version of Drupal do you use ?

 <?php

    function mymodule_menu() {
        $path = "events";

        $items[$path] = array(
            'title' => t('Events'),
            'page callback' => 'my_events_page',
            'access arguments' => array('access content'),
            'type' => MENU_NORMAL_ITEM,
            //'file' => 'my_events.pages.inc',
        );

        $items[$path . '/%'] = array(
            'title' => t('Events'),
            'page callback' => 'my_events_page',
            'page arguments' => array($depth),
            'access arguments' => array('access content'),
            'type' => MENU_CALLBACK,
            //'file' => 'my_events.pages.inc',
        );


        $items[$path . '/past'] = array(
            'title' => t('Past events'),
            'page callback' => 'my_events_past_page',
            'access arguments' => array('access content'),
            'type' => MENU_NORMAL_ITEM,
            //'file' => 'my_events.pages.inc',
        );

        return $items;
    }

    function my_events_page(){
        print "hello";
    }

    function my_events_past_page(){
        print "past";
    }

    ?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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