I'm Gilbert Pellegrom.

How To: Breadcrumbs in Wordpress

In this tutorial I am going to show you how to do proper, full breadcrumbs in Wordpress including nested categories and nested pages. Breadcrumbs are a pretty standard design pattern and can be very useful in a lot of website situations.

Breadcrumbs in Wordpress

I’m aware there are already some good plugins for adding breadcrumbs in Wordpress but I’m going to show you how to do it the good old fashioned way.

The PHP Code

Since I like to copy and paste I’ll post the full code first and then take a look at what it’s doing. You can just include this function in your theme’s “functions.php” file.

function get_breadcrumbs()
{
	global $wp_query;
 
	if ( !is_home() ){
 
		// Start the UL
		echo '<ul class="breadcrumbs">';
		// Add the Home link
		echo '<li><a href="'. get_settings('home') .'">'. get_bloginfo('name') .'</a></li>';
 
		if ( is_category() ) 
		{
			$catTitle = single_cat_title( "", false );
			$cat = get_cat_ID( $catTitle );
			echo "<li> &raquo; ". get_category_parents( $cat, TRUE, " &raquo; " ) ."</li>";
		}
		elseif ( is_archive() && !is_category() ) 
		{
			echo "<li> &raquo; Archives</li>";
		}
		elseif ( is_search() ) {
 
			echo "<li> &raquo; Search Results</li>";
		}
		elseif ( is_404() ) 
		{
			echo "<li> &raquo; 404 Not Found</li>";
		}
		elseif ( is_single() ) 
		{
			$category = get_the_category();
			$category_id = get_cat_ID( $category[0]->cat_name );
 
			echo '<li> &raquo; '. get_category_parents( $category_id, TRUE, " &raquo; " );
			echo the_title('','', FALSE) ."</li>";
		}
		elseif ( is_page() ) 
		{
			$post = $wp_query->get_queried_object();
 
			if ( $post->post_parent == 0 ){
 
				echo "<li> &raquo; ".the_title('','', FALSE)."</li>";
 
			} else {
				$title = the_title('','', FALSE);
				$ancestors = array_reverse( get_post_ancestors( $post->ID ) );
				array_push($ancestors, $post->ID);
 
				foreach ( $ancestors as $ancestor ){
					if( $ancestor != end($ancestors) ){
						echo '<li> &raquo; <a href="'. get_permalink($ancestor) .'">'. strip_tags( apply_filters( 'single_post_title', get_the_title( $ancestor ) ) ) .'</a></li>';
					} else {
						echo '<li> &raquo; '. strip_tags( apply_filters( 'single_post_title', get_the_title( $ancestor ) ) ) .'</li>';
					}
				}
			}
		}
 
		// End the UL
		echo "</ul>";
	}
}

We then include the following code on any pages you want breadcrumbs to appear:

<?php get_breadcrumbs(); ?>

The CSS Code

The CSS code is just adding some simple styling so that the links appear inline. This can be styled as you wish.

ul.breadcrumbs {
	list-style: none;
	padding: 0;
	margin: 0;
	font-size:12px;
}
ul.breadcrumbs li {
	float: left;
	margin: 0 5px 0 0;
	padding: 0;
}

The Explanation

So what are we doing here? Well lets start at the start.

  • First off don’t show breadcrumbs if it’s the homepage. If it’s not we add our first link which is to the top level homepage.
  • We then have a simple set of elseif statements which cover us for all the different situations we might find ourselves in. Some are fairly self explanatory like the seach, 404 and archive sections.
  • If it is a category we simply find the category ID then get list the parents of the current category. Wordpress helps us with this by providing a “get_category_parents()” function.
  • If we are on a single page it gets a bit more in-depth. We have to find the category ID but in a slightly different way to above. However once you get the category ID it’s just the same method as above plus the addition of the title of the page you are on.

Now pages are slightly more in depth but nothing too complex:

  • First off get the page title. Easy.
  • We then find the ancestors of the page and reverse the order of them. Thankfully Wordpress has a get_post_ancestors() function making our life much easier. The next line just adds the current post to the array of ancestors.
  • Finally we use a “foreach” loop to cycle through all of the ancestors and output them. The if statement in the loop makes sure that the last ancestor (the current page) doesn’t have a link.

So there you have it. Fully customizable, valid breadcrumbs in Wordpress. Please let me know what you think.

Download Source

Update 9th October

Thanks to mediadot for finding a small bug that left an un-closed <li> tag in the list. The code has been changed to remove this bug.

Update 26th October

Thanks to Uri Grinwald for finding a bug where li tags were in the wrong order on page breadcrumbs. The code has been changed to remove this bug.

Update 11th January

Thanks to antmeeks for pointing out some missing code in the article. I’ve also updated the description of how the pages are made as the get_post_ancestors() function made it far easier than before.

32 Comments

  • Ian M Rountree 5 months, 3 weeks ago

    Very sweet! However, oddly I just used this and line 19 returned a parsing error, for the line including:

    echo ” “;

    However, having removed the ul class and thrown the whole thing in a div classed as breadcrumbs, the effect seems the same, minus the parsing error. Hope it was just me?

  • Ian M Rountree 5 months, 3 weeks ago

    Silly me, in this code it’s line 8 – on MY code it was line 19.

    Code ettiquette fail.

  • Aldo 5 months, 3 weeks ago

    As Jan says, the correct code for line 8 would be:
    echo ‘<ul class=”breadcrumbs”>’;

    Thanks, Gilbert, for this code: very useful! :)

  • Micah 5 months, 3 weeks ago

    Actually, the best way to rewrite line 8 would be to add backslashes to the html, as such:

    echo ” “;

    The reason you use backslashes is because the backslash character (\) can be used to escape quotes and variables. The backslash allows PHP to essentially bypass the double quotation marks inside the HTML tag instead of crashing.

  • Micah 5 months, 3 weeks ago

    Oops, forgot to use entities!

    echo ‘<ul class=&#92”breadcrumbs&#92”>’;

  • Micah 5 months, 3 weeks ago

    Dang it. One more time.

    echo ‘<ul class=\“breadcrumbs\”>’;

    Feel free to correct the first comment with the correct code and delete these two follow ups!

  • Gilbert 5 months, 3 weeks ago

    Thanks guys for the heads up. I’ve updated the code now so it should be fixed. Enjoy.

  • Stevie Benge 5 months, 3 weeks ago

    Thanks for this code. This is a great homegrown alternative to the handful of breadcrumb plugins available for WP.

    You have some great WP oriented content on your site. I look forward to discovering more useful articles. Thanks again…

  • Gilbert 5 months, 3 weeks ago

    Hi Stevie. I’m glad you like this post and thanks for the complement.

  • Stevie Benge 5 months, 2 weeks ago

    My pleasure! Thinking about taking your WP CMS plugin for a spin…

  • faisalmalik1989 5 months, 2 weeks ago

    This function is awesome…

    I don’t need any breadcrumb plugin anymore. I hope this function will still be usable in the future wordpress…

  • mediadot 5 months, 2 weeks ago

    Excellent function, thank you. But there is a little error – current post has opened that never close. Any ideas how to fix it?

  • mediadot 5 months, 2 weeks ago

    Has an opened _li_

  • Gilbert 5 months, 2 weeks ago

    Thanks for pointing that one out. Updated the post.

  • mediadot 5 months, 2 weeks ago

    Thanks for your reply, but now if (is_single()) – the last parent category lost their open _li_ ))
    o_O

  • Gilbert 5 months, 2 weeks ago

    Ok changed it back. I thought you ment the if(is_single()) part was the one with the unclosed li. Which part do you mean?

  • mediadot 5 months ago

    Remove opening LI in line 36 helps to solve this problem. Thanks again for nice function

  • Gilbert 5 months ago

    Thanks mediadot. I’ve updated the post and code to reflect the changes.

  • BridieMacdonald 4 months, 3 weeks ago

    Easily add breadcrumbs to Wordpress – works like a charm http://bit.ly/2T8Icn

    This comment was originally posted on Twitter

  • Uri Grinwald 4 months, 2 weeks ago

    Hi,
    Thank you for making this code available but I was wondering if you could help troubleshoot a bug I found. My site consist mostly of pages and sub pages and when I insert the code this is the result of the output html breadcrumb.

    ul class=”breadcrumbs”> Dixon Hall » Our Services » Neighbourhood Programs

    As you can see the home page as an extra closing and the current page has no closing

    Thanks in advance.

  • Uri Grinwald 4 months, 2 weeks ago

    Sorry here is the code using plain html entities

    ul class="breadcrumbs"> <li><a href="http://ebizwindows.dynamic.ca">Dixon Hall</a></li></li><li> &raquo; <a href="http://ebizwindows.dynamic.ca/?page_id=5">Our Services</a></li><li> &raquo; Neighbourhood Programs</ul>

  • Gilbert 4 months, 2 weeks ago

    Hi Uri. Thanks for pointing that out. I’ve updated the code so that it is fixed. You can re-download the source code if you want to get the fixed code.

  • gilbitron 4 months, 2 weeks ago

    Updated my “How To: Breadcrumbs in Wordpress” article –> http://bit.ly/OKgWO

    This comment was originally posted on Twitter

  • Uri Grinwald 4 months, 2 weeks ago

    Thank you kindly will give it a re-try

  • antmeeks 2 months ago

    The breadcrumb generates the page trail & titles with no issues… However, it doesn’t show the title of posts, nor the post’s parent categories… I’m using on WP 2.9.1 -

  • Gilbert 2 months ago

    Hi antmeeks. Thanks for the heads up. I’ll have to check the compatibility for Wordpress v2.9+.

  • antmeeks 2 months ago

    I tried it again this morning by downloading the source and it worked. Originally I had just copied the function from your article… So obviously there is a difference between the two versions because now it works fine. Perhaps you should eliminate the source in the body of your article?

    Oh and BTW, nice work on this function! It’s absolutely perfect in it’s functionality and provides a very elegant, clean solution to a problem where a plugin would be overkill.

    I will certainly be following your site now – Thanks, Ant

  • Gilbert 1 month, 4 weeks ago

    @antmeeks Thanks for pointing that out. I’ve updated the article and the code. Appreciate the comments.


Pingbacks & Trackbacks

Your Opinion

(required)

(will not be shared & is required)