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

    function end_lvl(&$output, $depth=0, $args=array()) {
        // decrement the depth when we exit a ul

    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
        } else {
            // if not, unset the item for this depth since this isn't what we're going to display

    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.


  • 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

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.

  • 1
    actually it did not work for me, i had to change bit of code to find menu object corectly: if ( ( $locations = get_nav_menu_locations() ) && isset( $locations[ $menu_name ] ) ) { $menu = wp_get_nav_menu_object( $locations[ $menu_name ] ); $items = wp_get_nav_menu_items($menu->term_id); – Roman Dec 10 '14 at 1:25
  • Absolutely spot on! Thanks @Jules – Joey Urbansoul Jun 25 '19 at 9:25

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

  • 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

Here is the walker class that i develop for zurb foundation 5 breadcrumb element, this is helpful if you want to show your breadcrumb in unordered list tag.

      class BreadCrumbWalker extends Walker_Nav_Menu

        function start_lvl( &$output, $depth = 0, $args = array() )

        function end_lvl( &$output, $depth = 0, $args = array() )

        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;

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

          if( in_array('current-menu-item', $classes) OR in_array( 'current-menu-parent', $classes ) ){
            //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

            if( in_array('current-menu-item', $classes) ){
              $output .= '<li>'.$title.'</li>';
              $output .= '<li><a' . $attributes . '>' . $title . '</a></li>';

          }//if current


  • This class should be placed into the functions.php file. – dbasch May 8 '15 at 20:45

Why not do something similar to this;

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

Then where ever you want them just use;

<?php the_breadcrumb(); ?>
  • 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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