I’m messing around with Drupal again for a church web site. The task I’m working with at the moment is trying to make it so that the breadcrumb is based upon a menu other than than that Navigation menu (which is the normal way content breadcrumbs are set in Drupal). Long story short, we’ve chosen to make the Primary Links the site map rather than the more typical Navigation menu.
The technique that really ought to work is this:
menu_set_active_menu_name('primary-links');
$breadcrumb = menu_get_active_trail();
drupal_set_breadcrumb($breadcrumb);
That’s simple enough, but it doesn’t work. At least, it doesn’t work unless it gets called at some point very early in the request life cycle. After some digging through the Drupal API, I found that menu_get_active_trail() is actually defined like this:
function menu_get_active_trail() {
return menu_set_active_trail();
}
I vaguely remembered this from a year ago when I was last mucking with Drupal. This is a pretty common Drupal idiom. It’s basically the Drupal developer’s way of using the mutator (i.e., menu_set_active_trail()) simultaneously as a accessor and default setting. That’s fine. However, when you look into menu_set_active_trail() I found something wrong. The code looks like this (minus some code that I don’t want to spew here):
function menu_set_active_trail($new_trail = NULL) {
static $trail;
if (isset($new_trail)) {
$trail = $new_trail;
}
elseif (!isset($trail)) {
// LOTS OF CODE HERE TO CONFIGURE THE DEFAULT
// BASED UPON THE OUTPUT OF menu_get_active_menu_name()
}
return $trail;
}
Do you see the problem? If you happen to set the value returned by menu_get_active_menu_name() (via menu_set_active_menu_name()) in time, you can get it to setup your breadcrumb using some fairly smart code that does the right thing for you.
However, if you don’t set it before the first call to menu_set_active_trail(), you can never run that helpful default code ever again. There’s no way to unset $trail because $new_trail is ignored if it is unset. There’s no way to execute the default code without unsetting $trail since it’s all within this single function.
Bah! The correct solution is to move the default code into a separate method so that it can be called separately later and reused.
My work-around will probably be to install the Menu Breadcrumb module. I’m trying to keep the number of modules installed on this particular site very low, so I was hoping to avoid it. Yet, installing a module is going to work out better than me reinventing the wheel with a module of my own, in this case. It’s these little frustrations that drove me away from Drupal in my personal site. I’m probably being too picky and hypocritical, but whatever.
Cheers.
