Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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"';
}
share|improve this question
    
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? –  Joseph Apr 27 '12 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 Apr 27 '12 at 13:26

1 Answer 1

up vote 5 down vote accepted

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>';
        }
    }
}
share|improve this answer
    
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 Apr 30 '12 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. –  Stephen Harris Apr 30 '12 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 Apr 30 '12 at 14:41

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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