5

I want something like this

Home > Products > Steel > Nails

This information should come from the menu structure! I installed Breadcrumb NavXT but it seems that it only takes the path I defined (this is the parent and so on). But I need this from the menu structure not from the user. Do I have to set the parent page for each page or is there a solution which reads out the hierarchy from my menu? I didn't found a seeting Breadcrumb NavXT and it seems that I have to write a PHP script for that.

Edit: For my follow up question I added the following code:

if(in_array('current-menu-item', $item->classes)){
    $attributes .= ' class="active"';
}
2
  • I think that Breadcrumb NavXT builds the trail based on page hierarchy or category, whichever exists. In other words, Products would be the parent page/category of Steel which would be the parent page/category of the Nails page. How are your pages currently organized? Commented Apr 27, 2012 at 12:52
  • My menu looks like: Products > Steel > Nails. Some of the pages have a hierarchy. Here it looks like Steel > Big > Nails . So the hierarchy differs a little bit. But I want the hierarchy from the menu. I know one way to achive that would be setting the hierarchy for each page. But I don't know if the user would do that if he creates a new page ...
    – testing
    Commented Apr 27, 2012 at 13:26

1 Answer 1

5

The best way would be to use wp_nav_menu with a custom walker.

Prerequisites:

Useage

Wherever you want the breadcrumbs (for theme location 'primary'):

<?php wp_nav_menu( array( 
    'container' => 'none', 
    'theme_location' => 'primary',
    'walker'=> new SH_BreadCrumbWalker, 
    'items_wrap' => '<div id="breadcrumb-%1$s" class="%2$s">%3$s</div>'
 ) ); ?>

The custom walker

This is very basic. (This could be done another way -override display_element instead? - but I found this the most straightforward). This should live in your functions.php

class SH_BreadCrumbWalker extends Walker{
    /**
     * @see Walker::$tree_type
     * @var string
     */
    var $tree_type = array( 'post_type', 'taxonomy', 'custom' );

    /**
     * @see Walker::$db_fields
     * @var array
     */
    var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );

    /**
     * delimiter for crumbs
     * @var string
     */
    var $delimiter = ' > ';

    /**
     * @see Walker::start_el()
     *
     * @param string $output Passed by reference. Used to append additional content.
     * @param object $item Menu item data object.
     * @param int $depth Depth of menu item.
     * @param int $current_page Menu item ID.
     * @param object $args
     */
    function start_el(&$output, $item, $depth, $args) {

        //Check if menu item is an ancestor of the current page
        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $current_identifiers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' ); 
        $ancestor_of_current = array_intersect( $current_identifiers, $classes );     


        if( $ancestor_of_current ){
            $title = apply_filters( 'the_title', $item->title, $item->ID );

            //Preceed with delimter for all but the first item.
            if( 0 != $depth )
                $output .= $this->delimiter;

            //Link tag attributes
            $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
            $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
            $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
            $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

            //Add to the HTML output
            $output .= '<a'. $attributes .'>'.$title.'</a>';
        }
    }
}
3
  • Thanks for your awesome work. Is it possible to add a wrapper for the last element? I want to change the styling. Something like a <span class="active"> wrapper would be nice. And I think I cannot get rid of the ul wrap or?
    – testing
    Commented Apr 30, 2012 at 14:17
  • 1
    The example I give doesn't wrap it in ul tags. It wraps it in <div id="breadcrumb-%1$s" class="%2$s">%3$s</div>. To alter the mark-up for the last element only check if current-menu-item is in the $item->classes array and style accordingly. Commented Apr 30, 2012 at 14:23
  • Thanks for your fast response! You're right. I removed that code and as default the ul was taken. I also added the code to your script. Now it works as expected! Thanks again!
    – testing
    Commented Apr 30, 2012 at 14:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.