Book outline overrides menu breadcrumb

SimonVlc - December 29, 2008 - 23:14
Project:Menu Breadcrumb
Version:6.x-1.1
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:active
Description

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.

#1

starkos - January 24, 2009 - 14:21

+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.

#2

starkos - January 25, 2009 - 15:56

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.

<?php
/**
* 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));
  }
}
?>

#3

starkos - January 25, 2009 - 16:13

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

<?php
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));
}
?>

#4

Johnny vd Laar - February 26, 2009 - 12:14

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

<?php
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:

<?php
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)

#5

Johnny vd Laar - February 26, 2009 - 12:40

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

AttachmentSize
menu_breadcrumb.patch 2.18 KB

#6

JoepH - April 23, 2009 - 11:45

#5 does not work here.

#7

Johnny vd Laar - May 18, 2009 - 11:39

did you clear your drupal cache after applying the patch?

as it works for me for the forums

#8

lrobeson - October 22, 2009 - 17:09

No luck with #5 either. :-(

#9

jweowu - October 27, 2009 - 04:20

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

 
 

Drupal is a registered trademark of Dries Buytaert.