Wordpress Breadcrumbs

I have been playing about with breadcrumb trails in Wordpress recently so I thought I would post the code here in case anyone else finds it useful. The basic idea is to try to find out where the current page is situated within the site. This means checking for pages and categories with their parents. Once we get down to the post level we need to try some things in order to find out where the current post is within the site.

Once the trail array has been filled with items it is looped through and converted into a string.

To use this function put the following code into your functions.php file in your template.

<?php
/**
 * Echo or return a formatted list of breadcrumbs.
 *
 * @param  array  $args An array of arguments to controll the output of the 
 *                      function.
 * @return string       The breadcrumb list.
 */
function get_breadcrumbs($args = array())
{
    global $post;
   
    if (is_string($args)) {
        parse_str($args, $args);
    }
 
    // Set up defaults.
    $defaults = array(
        'separator'   => ' &gt; ',
        'linkFinal'   => false,
        'echo'        => true,
        'printOnHome' => true, 
        'before'      => '', 
        'after'       => '', 
    );
 
    // Merge the defaults with the parameters.
    $options = array_merge($defaults, (array)$args);
 
    // Initialise the trail with the current post.
    $trail = array($post);
    
    // Initialise the output.
    $output = '';
    
    $currentCategory = 0;
 
    if (is_front_page() == true && $options['printOnHome'] == false) {
        /**
         * If this is the front page and the option to prevent priting on the
         * home page is disabled then echo or return the empty string depending
         * on the echo option.
         */
        if ($options['echo'] == true) {
            echo $output;
        }
        return $output;
    }
    
    if (is_page()) {
        // If the current page is a page.
        $parent = $post;
        while ($parent->post_parent) {
            $parent = get_post($parent->post_parent);
            array_unshift($trail, $parent);
        }
    } elseif (is_category()) {
        // The current page is a category page.
        $trail = array();
        $currentCategory = get_query_var('cat');
        $category        = get_category($currentCategory);
        while ($category->category_parent > 0) {
            array_unshift($trail, $category);
            $category = get_category($category->category_parent);
        }
        // Add the final category to the trail.
        array_unshift($trail, $category);
    } else {
        // The current page will be a post or set of posts.
        $path = explode('/', $_SERVER['REQUEST_URI']);
        $path = array_filter($path);
        while (count($path) > 0) {
            $page = get_page_by_path(implode('/', $path));
            if ($page != NULL) {
                array_unshift($trail, $page);
            }
            array_pop($path);
        }
        
        if (count($trail) == 1) {
            // No pages found in path, try using categories.
            $category = get_the_category();
            $category = $category[0];
            while ($category->category_parent > 0) {
                array_unshift($trail, $category);
                $category = get_category($category->category_parent);
            }
            array_unshift($trail, $category);
        }
    }
 
    $show_on_front = get_option('show_on_front');
    if ('posts' == $show_on_front) {
        // The home page is a list of posts so just call it Home.
        $output .= '<li class="breadcrumb-item" id="breadcrumb-0"><a href="' . get_bloginfo('home') . '" title="Home">Home</a></li>' . "\n"; // home page link
    } else {
        // Otherwise the front page is a page so get the page name.
        $page_on_front = get_option('page_on_front');
        $home_page = get_post($page_on_front);
        $output .= '<li class="breadcrumb-item" id="breadcrumb-' . $home_page->ID . '"><a href="' . get_bloginfo('home') . '" title="' . $home_page->post_title . '">' . $home_page->post_title . '</a></li>' . "\n"; // home page link
        if ($trail[0]->ID == $page_on_front) {
            array_shift($trail);
        }
    }
 
    if (is_front_page() == false) {
        // If we aren't on the home page then construct the output. 
        foreach ($trail as $key => $page) {
            // Every item in the trail will be either a post/page object or a category.
            if (count($trail) - 1 == $key && $options['linkFinal'] == false) {
                // If we are on the last page and the option to link the final link is true.
                if (isset($page->post_title)) {
                    $output .= '<li class="breadcrumb-item" id="breadcrumb-' . $page->ID . '">' . $options['separator'] . ' ' . $page->post_title . '</li>' . "\n";
                } elseif (isset($page->cat_name)) {
                    $output .= '<li class="breadcrumb-item" id="breadcrumb-cat-' . $page->term_id . '">' . $options['separator'] . ' ' . $page->cat_name . '</li>' . "\n";
                }
            } else {
                // Create the link to the page or category
                if (isset($page->post_title)) {
                    $output .= '<li class="breadcrumb-item" id="breadcrumb-' . $page->ID . '">' . $options['separator'] . '<a href="' . get_page_link($page->ID) . '" title="' . $page->post_title . '">' . $page->post_title . '</a></li>' . "\n";
                } elseif (isset($page->cat_name)) {
                    $output .= '<li class="breadcrumb-item" id="breadcrumb-cat-' . $page->term_id . '">' . $options['separator'] . '<a href="' . get_category_link($page->term_id) . '" title="' . $page->cat_name . '">' . $page->cat_name . '</a></li>' . "\n";
                }
            }
        }
    }
    
    // Finish off the html of the ul
    $output = "<ul>\n" . $output . "</ul>\n";
    
    // Add other elements
    $output = $options['before'] . $output .  $options['after'];
    
    if ($options['echo'] == true) {
        // Print out the $output variable.
        echo $output;
    }
    // Return 
    return $output;
}

Print out the breadcrumb trail on your page like this:

Several options are also available to change the way the function works. These are as follows:

  • separator: The string to separate the items in the breadcrumb trail, defaults to &gt;.
  • linkFinal: Whether or not to print the last link as a link. Defaults to false.
  • echo: Whether or not to print out the breadcrumb in the function. Defaults to true.
  • printOnHome: Print the breadcrumb on the home page. Defaults to true.

You can set the options for the get_breadcrumbs() function in much the same way as normal Wordpress functions. This can be through a parameter string or a array like this.

<?php
get_breadcrumbs(
    array(
        'separator'   => ' &gt; ',
        'linkFinal'   => false,
        'echo'        => true,
        'printOnHome' => false, 
    )
);
?>

This will print out something like the following:

<ul> 
<li class="breadcrumb-item" id="breadcrumb-0"><a href="http://www.example.com/wordpress_test" title="Home">Home</a></li> 
<li class="breadcrumb-item" id="breadcrumb-174"> &gt; <a href="http://www.example.com/wordpress_test/level-1" title="Level 1">Level 1</a></li> 
<li class="breadcrumb-item" id="breadcrumb-173"> &gt; <a href="http://www.example.com/wordpress_test/level-1/level-2" title="Level 2">Level 2</a></li> 
<li class="breadcrumb-item" id="breadcrumb-172"> &gt;  Level 3</li> 
</ul>

Because Wordpress is one of those applications that can be set up in a number of different ways I have tried to account for as many situations as I can. However, if you try this breadcrumb function out and it doesn't work as expected post a comment here and let me know.

UPDATE: Added before and after options to the breadcrumb output string.

Comments

While looking for php isset on Sunday I came across your blog and post about Wordpress Breadcrumbs | #! code. I could not believe the amount of quality material that exists on this site. The site is extremely eye catching and pulls the reader straight it, the articles are great quality and are very professionally written. I have seen too many of these sites where it looks like they pay an 8 year old to do the writing - Not this one. Your site is easily the best that I have seen in a long while.
Permalink

Add new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
1 + 0 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.