Finding an existing Page's Callback Function in Drupal

Submitted by allan on Fri, 01/18/2013 - 12:13
So have you ever been stuck debugging where the heck that stupid page comes from that some random module seems to have placed in a configuration section that seems to be nothing related to the module itself? Well there are other use cases for what I'm about to show you as well but this is a cool little pro tip to get you on your feet and get you some place to start debugging.

Via the Command-Line

First thing's first, you must have drush to make this work best. If you know me, you know I find working from command-line to be one of the best things since the computer was made. So make sure you have it installed. If you are an Ubuntu fan like I am, follow this tutorial. Once you got drush going, navigate to your drupal installation and type:
drush eval "print_r(menu_get_item('path/to/page'))"
A perfect example might be:
drush eval "print_r(menu_get_item('node/add/article'))"

Via Devel

If you don't have access to commandline, you can always do things the Devel way. First make sure Devel is installed, and enabled. Second you need to go to admin/structure/block and enable the Execute PHP block. Stick it in the footer or somewhere it won't obstruct your view. Next, if you don't see the block magically appear, make sure your role has permission to execute PHP. Check at admin/people/permissions#module-devel. Last, type dvm(menu_get_item('node/add/article')); into the textbox in the block and hit execute.

The Results

Array
(
    [path] => node/add/article
    [load_functions] =>
    [to_arg_functions] =>
    [access_callback] => node_access  <-- IMPORTANT
    [access_arguments] => a:2:{i:0;s:6:"create";i:1;s:7:"article";}
    [page_callback] => node_add   <-- IMPORTANT
    [page_arguments] => a:1:{i:0;s:7:"article";}
    [delivery_callback] =>
    [fit] => 7
    [number_parts] => 3
    [context] => 0
    [tab_parent] =>
    [tab_root] => node/add/article
    [title] => Article
    [title_callback] => check_plain
    [title_arguments] =>
    [theme_callback] =>
    [theme_arguments] => a:0:{}
    [type] => 6
    [description] => Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.
    [position] =>
    [weight] => 0
    [include_file] => modules/node/node.pages.inc   <-- IMPORTANT
    [href] => node/add/article
    [tab_root_href] => node/add/article
    [tab_parent_href] =>
    [options] => Array
        (
        )

    [access] =>
    [original_map] => Array
        (
            [0] => node
            [1] => add
            [2] => article
        )

)
Note that I pointed out what was important here. So in this case, our function is in modules/node/node.pages.inc and calling node_add().

Final Thoughts

This was one of the first tricks Travis Tidwell over at AllPlayers taught me. It really does come in handy. At the very least it gives you a place to start the majority of the time. Happy coding!