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 was looking for a quick and dirty method to output a breadcrumb navigation on a WP site, without requiring the installation of a plugin and also leveraging the built-in WP menu.

Here's what I came up with. I'm curious to know if there is a better solution I am missing, and/or if there is anything obviously wrong with doing it this way. So far in my testing it works quite well.

class BreadcrumbWalker extends Walker_Nav_Menu {
    private $i_current_page_id;
    private $i_depth;
    private $a_output;

    function __construct() {
        // sets our current page so we know when to exit
        $this->i_current_page_id = get_queried_object()->ID;
    }

    function start_lvl(&$output, $depth=0, $args=array()) {
        // increment the depth every time a new ul is entered
        $this->i_depth++;
    }

    function end_lvl(&$output, $depth=0, $args=array()) {
        // decrement the depth when we exit a ul
        $this->i_depth--;
    }

    function start_el(&$output, $item, $depth=0, $args=array()) {
        // if this value is zero, we're starting a new branch
        if($item->menu_item_parent == 0) {
            // reset the output array and depth counters
            $this->a_output = array();
            $this->i_depth = 0;
        }
        // if we haven't set the representative menu item for this depth, do so
        if(!isset($this->a_output[$this->i_depth])) {
            $this->a_output[$this->i_depth] = '<a href="' . get_permalink($item->object_id) . '">' . $item->title . '</a>';
        }
    }

    function end_el(&$output, $item, $depth=0, $args=array()) {
        if($this->i_current_page_id == $item->object_id) {
            // check to see if this is our last item, if so display the breadcrumb
            if($this->i_depth > 0) {
                // but only show it if we actually have a breadcrumb trail
                $this->display_breadcrumb();
            }
        } else {
            // if not, unset the item for this depth since this isn't what we're going to display
            unset($this->a_output[$this->i_depth]);
        }
    }

    function display_breadcrumb() {
        // implode our array into a string
        echo implode(' &raquo; ', $this->a_output);
    }
}

Basically what I'm doing is using the Walker_Nav_Menu methods to set an output array that uses the depth as its key, and once the end_el method is called, if it's not the ID of the page that's the end of the breadcrumb, it unsets the item at that depth and keeps iterating over the array. If it is the correct ID, it calls the display_breadcrumb method to output the menu.

Thanks in advance for any input. I feel like there's probably a better way to do this, but at the moment am stumped as to what that might be.

Cheers.

share|improve this question
    
Down voted for "without using a plugin" because it's a ridiculous requirement. WordPress is plugins. The hooks system and plugins (or your theme's functions.php file, because they can do the same things -- mostly) is where WordPress gets its flexibility. If you mean, "without requiring the user to install another, already-made plugin" indicate that, don't rule out plugins entirely. –  chrisguitarguy Jan 26 '13 at 5:27
    
Thanks for the tip. I should have been more explicit in my wording. Due to some specific constraints of where this is being used I'd like to be able to do it as part of the theme's functions.php file, and not have to rely on a third-party plugin. –  jtwg Jan 26 '13 at 6:00
    
Perfect. Upvote revoked! Sorry if I came off angrily. Not my intention -- "No plugin" posts make me frustrated. –  chrisguitarguy Jan 26 '13 at 6:16
    
Look here wordpress.stackexchange.com/questions/50425/…, exact php class you need! –  realmag777 Jun 3 '13 at 8:54

3 Answers 3

I wrote a plugin that just does this!

  • Breadcrumbs based on WP Nav Menu
  • Includes Rich Snippets (Microdata)
  • Three different style
  • Custom CSS editor
  • Various settings
  • Multilanguage ready, just English for now

You can find it at: http://codecanyon.net/item/wp-nav-menu-breadcrumbs/4706192

share|improve this answer
3  
"... method to output a breadcrumb navigation on a WP site, without requiring the installation of a plugin" -- How can your plugin meet that requirement? –  s_ha_dum May 31 '13 at 22:53

Why not do something similar to this;

function the_breadcrumb() {
if (!is_home()) {
    echo '<a href="';
    echo get_option('home');
    echo '">';
    bloginfo('name');
    echo "</a> » ";
    if (is_category() || is_single()) {
        the_category('title_li=');
        if (is_single()) {
            echo " » ";
            the_title();
        }
    } elseif (is_page()) {
        echo the_title();
    }
}
}

Then where ever you want them just use;

<?php the_breadcrumb(); ?>
share|improve this answer
    
Thanks for the response, but what I'm doing here is replicating the menu hierarchy created via WP's built-in menus as a breadcrumb to indicate the user's place hierarchically. –  jtwg Jan 26 '13 at 6:02

I couldn't believe there is not a single FREE plugin available that does this. So I wrote my own function. Here you go. Just copy this to your functions.php:

function my_breadcrumb($theme_location = 'main', $separator = ' &gt; ') {

    $items = wp_get_nav_menu_items($theme_location);
    _wp_menu_item_classes_by_context( $items ); // Set up the class variables, including current-classes
    $crumbs = array();

    foreach($items as $item) {
        if ($item->current_item_ancestor || $item->current) {
            $crumbs[] = "<a href=\"{$item->url}\" title=\"{$item->title}\">{$item->title}</a>";
        }
    }
    echo implode($separator, $crumbs);
}

Then, anywhere in your theme you can output the breadcrumb like this:

<?php my_breadcrumb('menu-slug'); ?>

This code can easily be extended, by omitting the $theme_location parameter and getting a list of every available menu, only outputting the result if the $crumbs array isn't empty. I may write a blog post about this or turn it into a free plugin soon. Keep you updated.

You could also add a class or differnt markup the current item by checking for $item->current.

share|improve this answer

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.