The hook_menu() keys for those panels are arbitrary (defined by you), so I can't post a 100% exact example, but here's one general solution of how to "hack" or intercept an existing hook_menu() item:
- Go to the menu_router table.
- Search for the URL path that you defined for your panel. You can start by using an exact-match search, and if nothing appears, do a wildcard (%) search such as this:
select * from menu_router where path like "%bar%"
instead of `...path = "foo/bar/baz". This will tell you everything about that menu item, what module defined it, what function it calls, what are it's arguments, and what loading function for the arguments (if any) there are.
- Armed with this information, you can go to the module that defined the menu item. Go to the hook_menu implementation of that module and look for that key. Take a note of the different keys that compose the menu item. Sometimes it is overkill to define your own menu item when all you need is to change is, let's say, the title callback. For this we then use the hook_menu_alter().
- Implement hook_menu_alter in your custom module.
Example for item # 4.
/**
* Implementation of hook_menu_alter.
*
* Intercept 'foo/bar/baz' and 'taxonomy/term/%taxonomy_term'.
*/
function mymodule_menu_alter(&$items) {
// The string to the right is the name of the function that is going to get called
// to determine that page's title. We just substituted what defined there by
// someone else with our own function.
$items['foo/bar/baz']['title callback'] = 'mymodule_panel_title_callback';
// Here I modify a separate menu item.
// Redirect current page workflow to my module.
// Note that the function taxonomy_term_load() will be called with whatever argument is in the
// third element of the path, so "taxonomy/term/123" will call taxonomy_term_load(123) and the
// result will be passed to mymodule_taxonomy_term_page().
$items['taxonomy/term/%taxonomy_term']['page callback'] = 'mymodule_taxonomy_term_page';
// I'm doing this to state the "obvious" - that taxonomy_term_load() will be passed 123 in "taxonomy/term/123".
// Also to say that there's not much you can do to to modify this particular menu item attribute.
// Since %taxonomy_term is part of the menu item key, if you modify that to be something else, such as
// %mymodule_taxonomy_term, you would be basically defining a new menu item (If I'm not mistaken).
// If you find yourself in the position that you need to modify the "auto-loader wildcard component", then
// that might be your cue to define your own menu item, and then call back 'taxonomy/term/%taxonomy_term'
// from your own callback.
$items['taxonomy/term/%taxonomy_term']['page arguments'] = array(2);
}
Now to make things more complex, let's say that as part of your problem, you do need to modify the "auto-loader wildcard component" for 'taxonomy/term/%taxonomy_term'
, and that this menu item is defined by Drupal core taxonomy. Like I stated in my comments above, toying with that on your hook_menu_alter() could possible mess up your menu definitions.
So we are left with two options. Define your own menu item and 1) Call back the menu item defined by Core from your own menu item or 2) Just copy the code that is in the body of the function called by the original menu item to your custom function. If doing #2 and you get an error make your you include the file where the core function rests my using module_load_include(). Note that I used core as an example, but the technique could be applied as well to contrib modules.
/**
* Implementation of hook_menu().
*/
function mymodule_menu() {
$items = array();
// Defining an arbitrary path, change it to what makes logic for you.
// Using a simple wildcard.
$items['mymodule/term/%'] = array(
'page callback' => 'mymodule_taxonomy_term_page',
// Define other arguments, skipping for the sake of brevity.
);
// This menu item will call function mymodule_taxonomy_term_load(), and pass
// the results of that call to mymodule_taxonomy_term_page.
// Note that the path I define here conflicts with the path above, and that you should use either or, but not both.
// Else menu router will get confused and will not know which one to call. The same applies to paths created by
// core or contrib, it is important not to define them twice.
$items['mymodule/term/%mymodule_taxonomy_term'] = array(
'page callback' => 'mymodule_taxonomy_term_page',
// Stating that mymodule_taxonomy_term_load() will be passed the 3rd argument in the path (count is zero-based).
'page arguments' => array(2),
// Define other arguments, skipping for the sake of brevity.
);
return $items;
}
// Meantime, in another part of your module...
/**
* Returns a taxonomy term object based.
*/
function mymodule_taxonomy_term_load($term) {
// Here you could do all the custom logic you want. Depending on what you put here, you might be
// able to even support numeric term ids and non-numeric term names in the same path. Example:
if(is_numeric($term)) {
$term_object = mymodule_taxonomy_term_load($term);
} else {
// String detected.
// Do some cleanup first, and then try to load a taxonomy term with the cleaned string.
$clean_term_string = somecleanup_function($term);
$term_object = taxonomy_get_term_by_name($clean_term_string);
}
if($term_object) {
// Profit!
return $term_object;
} else {
// Return something we can reliably validate against in our callback...
return FALSE;
}
}
// And then in your hook_menu() callback...
/**
* Render a page based on term?
*
* @param var $term - A term object if mymodule_taxonomy_term_load() was successfull, else FALSE.
*/
function mymodule_taxonomy_term_page($term) {
if($term === FALSE) {
// Degrade gracefully, e.g., show a custom error page...
} else {
// If our example `'taxonomy/term/%taxonomy_term'` is defined by Core, and we did not implement hook_menu_alter() for it,
// call whatever function that callback defines. Note that we accomplished our mission here by loading $term the
// way we wanted to in the auto-loader function, so we don't really need much processing here, but we could do more if needed.
return somefunction_defined_bycore($term);
// Else the other option was to copy and paste somefunction_defined_bycore()'s function body into here and return it.
// Do some processing...
return $something;
}
}