Hi there,

I just noticed that when I outline a page under a book, it loses it´s menu breadcrumb, and uses the book one.

Is there any option to avoid that? Thanks in advance, Simon.

CommentFileSizeAuthor
#5 menu_breadcrumb.patch2.18 KBJohnny vd Laar
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

starkos’s picture

+1. It also doesn't work for forum containers.

Here's my use case (which worked OTB on 5.x grrr...): I have several product pages. Each product has documentation (a book) and discussions (a forum container). I set up my menu like this:

  • Navigation
    • ProjectOne
      • Documentation
      • Discussions

When I drill down into a child page of the book, I would expect the breadcrumb to read: Home > ProjectOne > Documentation. That is, from a child page I can return the top of the book, or the associated project. If I drill down farther into the book, I'd expect the breadcrumb to grow to include all parent pages, without losing the association to the root product page. What I get now is Home > Documentation.

When I drill down into a forum, I'd expect Home > ProjectOne > Discussion. What I get is Home > Forums > Discussion.

This seems like a bug in core, since the documentation indicates that the breadcrumb should reflect the Navigation menu. But I've spent hours reading all the discussions surrounding breadcrumbs and don't expect them to sort it anytime soon.

I'm working on a custom-coded breadcrumb as a workaround; when I get it working I'll post it here on the off-chance it'll help someone out.

starkos’s picture

I managed to get breadcrumbs working with a menu in a way that seems intuitive. It supports books and forums, and should support any other content type. It is self-contained in a module, and does not require any template changes. But it is a real hack. I don't know if this is the right approach for the Menu Breadcrumb module -- I'd like to believe there is a better way -- but I present it on the off-chance it will help someone out.

/**
 * Try to find a menu link which matches the supplied URI. This implementation searches
 * for an item within a specific menu; remove the AND clause to search all menus. Note
 * that D6 creates menus for books. If you do not limit your search to a particular menu
 * you must set your custom menu item weight to a value less than zero to give it priority
 * over these system-generated menus (the reason for the ORDER BY in the query).
 * 
 * If this code makes it into a standalone module, the criteria (menu name) ought to be
 * pulled from a user-set configuration value, obviously.
 *
 * @param string $uri
 */
function _mymodule_find_menu($uri) {
  return db_result(db_query("SELECT mlid FROM {menu_links} WHERE link_path = '%s' AND menu_name = 'navigation' ORDER BY weight", $uri));
}


/**
 * Build a better breadcrumb, merging the information in the current, system-supplied
 * breadcrumb with any hierarchy available in the menu system. 
 */
function mymodule_preprocess(&$variables, $hook) {
  if ($hook == "page") {
    // Start with an empty breadcrumb and build it from the bottom up
    $bc = array();
    
    // Let's check the current page first
    $curi = urldecode(request_uri());
    $curi = substr($curi, 1, strlen($curi));    
    $mid  = _mymodule_find_menu($curi);
    $matches_current_page = $mid;
    
    // If the current page doesn't match, scan the current breadcrumb for matching
    // menu items. Work through it backwards, adding any non-matching items to my
    // new breadcrumb-in-progress.
    if (!$mid) {
      $old_bc = array_reverse(drupal_get_breadcrumb());
      foreach ($old_bc as $bitem) {
        // Extract the href from the item HTML
        preg_match('/\<a href="\/(.*?)">/', $bitem, $matches);
        $mid = _mymodule_find_menu($matches[1]);
        if ($mid) {
          break;
        } else {
          $bc[] = $bitem;
        }
      }
    }
    
    // If I found a matching menu item, use it to populate the breadcrumb. If the
    // menu matches the current page, then I skip the first item (because the
    // current page shouldn't appear in the breadcrumb).
    if ($mid) {
      $mlink = menu_link_load($mid);
      if ($matches_current_page) {
        $mlink = menu_link_load($mlink['plid']);
      }

      while ($mlink) {
        $bc[] = l($mlink['title'], $mlink['href']);
        $mlink = menu_link_load($mlink['plid']);
      }

      $bc[] = l(t('Home'), NULL);
    }

    // Replace the old breadcrumb with my new one
    $variables['breadcrumb'] = theme_breadcrumb(array_reverse($bc));
  }
}
starkos’s picture

A small but important fix: convert path aliases to system URIs before trying to locate a matching menu item.

function _mymodule_find_menu($uri) {
  if ($src = drupal_lookup_path('source', $uri)) {
    $uri = $src;
  }
  return db_result(db_query("SELECT mlid FROM {menu_links} WHERE link_path = '%s' AND menu_name = 'navigation' ORDER BY weight", $uri));
}
Johnny vd Laar’s picture

an easier solution is to add this in the menu_breadcrumbs module:

function menu_breadcrumb_preprocess_forums(&$variables) {
  menu_breadcrumb_init();
}

downside is that the menu_breadcrumb_init() function is called twice now. but it's because of the forum module that overrides the breadcrumb in the template_breadcrumb_preprocess_forums function in the forum module that this is needed.

i didn't test this approach for the books module but i assume the problem will be solved by adding this:

function menu_breadcrumb_preprocess_books(&$variables) {
  menu_breadcrumb_init();
}

but someone who actually uses the book module should test this to be sure! ;)

ofcourse you can also place this in a seperate module (you'll have to rename the function then to mycustommodule_preprocess_forums)

Johnny vd Laar’s picture

FileSize
2.18 KB

ok it turns out that my previous approach didn't really work perfect. this new approach (in the patch) has a static variable which solves all problems for me

joep.hendrix’s picture

#5 does not work here.

Johnny vd Laar’s picture

did you clear your drupal cache after applying the patch?

as it works for me for the forums

OldAccount’s picture

No luck with #5 either. :-(

jweowu’s picture

FWIW, #595282: Menu weights provides a solution to this.

xurizaemon’s picture

Status: Active » Closed (duplicate)

#595282: Menu weights will resolve this issue, and is available in CVS and the upcoming -dev tarball.

I'm unsure if I should mark this as a duplicate of that ticket - but I'm going to, because the fix is in CVS already, and will be available for you to test via the 6.x-1.x-dev tarball in a few hours.

Please re-open this (long-standing) issue if that doesn't resolve things for you. If it does, please report as much on #595282: Menu weights.