Making breadcrumb with wp_nav_menu

Question

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.

0
jtwg 1 month 0 Answers 16 views 0

Leave an answer