Hi, I'm a web developer and blogger from Russia. My nickname is Dimox.
Sorry for my English, it's not my native. Read more about me and my blog.

WordPress Breadcrumbs Without a Plugin

WordPress Breadcrumbs Without a Plugin

Breadcrumbs is an important element of a web site navigation, which boosts his usability. Especially it concerns to a sites with a complex structure. Unfortunatelly, I don’t use breadcrumbs on my sites, may be because their structure is very simple or because I could not find a way of making breadcrumbs, suitable for me.

I have seen a different ways of a breadcrumbs implementation on WordPress sites, but not one of them I does not like, because all of them does not display a full chain of links. So I have created my version of WordPress breadcrumbs without a plugin.

Yes, there is a ready plugins for WordPress breadcrumbs, but I prefer to use a short code snippets, which doing the same.

Features of my version of WordPress breadcrumbs

  • Displays a full chain of links to the current page. For example, if the current post is in a second level category, so breadcrumbs will looks like this:

    Home » Category » Subcategory » Post Title

    But all, what I have seen, displays only such an option (excluding plugins):

    Home » Subcategory » Post Title

    The same applies to pages and subpages. For example, for a 3rd level page breadcrumbs will looks like this:

    Home » Page Level 1 » Page Level 2 » Page Level 3

  • Breadcrumbs is appearing on a following types of WordPress pages:

    • paged navigation (like sitename.com/page/2/);
    • category archive;
    • tag archive;
    • daily archive;
    • monthly archive;
    • yearly archive;
    • author archive;
    • single post page;
    • single page;
    • attachment page;
    • search results;
    • 404 error page.
  • adding a page number (if archive page is second or more);

  • custom symbol of delimiter;

  • custom text for a ‘Home’ link;

  • current crumb styling;

  • integrated Google rich snippets.

WordPress breadcrumbs function (last updated: 2014.05.26)

function dimox_breadcrumbs() {

	/* === OPTIONS === */
	$text['home']     = 'Home'; // text for the 'Home' link
	$text['category'] = 'Archive by Category "%s"'; // text for a category page
	$text['search']   = 'Search Results for "%s" Query'; // text for a search results page
	$text['tag']      = 'Posts Tagged "%s"'; // text for a tag page
	$text['author']   = 'Articles Posted by %s'; // text for an author page
	$text['404']      = 'Error 404'; // text for the 404 page

	$show_current   = 1; // 1 - show current post/page/category title in breadcrumbs, 0 - don't show
	$show_on_home   = 0; // 1 - show breadcrumbs on the homepage, 0 - don't show
	$show_home_link = 1; // 1 - show the 'Home' link, 0 - don't show
	$show_title     = 1; // 1 - show the title for the links, 0 - don't show
	$delimiter      = ' » '; // delimiter between crumbs
	$before         = '<span class="current">'; // tag before the current crumb
	$after          = '</span>'; // tag after the current crumb
	/* === END OF OPTIONS === */

	global $post;
	$home_link    = home_url('/');
	$link_before  = '<span typeof="v:Breadcrumb">';
	$link_after   = '</span>';
	$link_attr    = ' rel="v:url" property="v:title"';
	$link         = $link_before . '<a' . $link_attr . ' href="%1$s">%2$s</a>' . $link_after;
	$parent_id    = $parent_id_2 = $post->post_parent;
	$frontpage_id = get_option('page_on_front');

	if (is_home() || is_front_page()) {

		if ($show_on_home == 1) echo '<div class="breadcrumbs"><a href="' . $home_link . '">' . $text['home'] . '</a></div>';

	} else {

		echo '<div class="breadcrumbs" xmlns:v="http://rdf.data-vocabulary.org/#">';
		if ($show_home_link == 1) {
			echo '<a href="' . $home_link . '" rel="v:url" property="v:title">' . $text['home'] . '</a>';
			if ($frontpage_id == 0 || $parent_id != $frontpage_id) echo $delimiter;
		}

		if ( is_category() ) {
			$this_cat = get_category(get_query_var('cat'), false);
			if ($this_cat->parent != 0) {
				$cats = get_category_parents($this_cat->parent, TRUE, $delimiter);
				if ($show_current == 0) $cats = preg_replace("#^(.+)$delimiter$#", "$1", $cats);
				$cats = str_replace('<a', $link_before . '<a' . $link_attr, $cats);
				$cats = str_replace('</a>', '</a>' . $link_after, $cats);
				if ($show_title == 0) $cats = preg_replace('/ title="(.*?)"/', '', $cats);
				echo $cats;
			}
			if ($show_current == 1) echo $before . sprintf($text['category'], single_cat_title('', false)) . $after;

		} elseif ( is_search() ) {
			echo $before . sprintf($text['search'], get_search_query()) . $after;

		} elseif ( is_day() ) {
			echo sprintf($link, get_year_link(get_the_time('Y')), get_the_time('Y')) . $delimiter;
			echo sprintf($link, get_month_link(get_the_time('Y'),get_the_time('m')), get_the_time('F')) . $delimiter;
			echo $before . get_the_time('d') . $after;

		} elseif ( is_month() ) {
			echo sprintf($link, get_year_link(get_the_time('Y')), get_the_time('Y')) . $delimiter;
			echo $before . get_the_time('F') . $after;

		} elseif ( is_year() ) {
			echo $before . get_the_time('Y') . $after;

		} elseif ( is_single() && !is_attachment() ) {
			if ( get_post_type() != 'post' ) {
				$post_type = get_post_type_object(get_post_type());
				$slug = $post_type->rewrite;
				printf($link, $home_link . $slug['slug'] . '/', $post_type->labels->singular_name);
				if ($show_current == 1) echo $delimiter . $before . get_the_title() . $after;
			} else {
				$cat = get_the_category(); $cat = $cat[0];
				$cats = get_category_parents($cat, TRUE, $delimiter);
				if ($show_current == 0) $cats = preg_replace("#^(.+)$delimiter$#", "$1", $cats);
				$cats = str_replace('<a', $link_before . '<a' . $link_attr, $cats);
				$cats = str_replace('</a>', '</a>' . $link_after, $cats);
				if ($show_title == 0) $cats = preg_replace('/ title="(.*?)"/', '', $cats);
				echo $cats;
				if ($show_current == 1) echo $before . get_the_title() . $after;
			}

		} elseif ( !is_single() && !is_page() && get_post_type() != 'post' && !is_404() ) {
			$post_type = get_post_type_object(get_post_type());
			echo $before . $post_type->labels->singular_name . $after;

		} elseif ( is_attachment() ) {
			$parent = get_post($parent_id);
			$cat = get_the_category($parent->ID); $cat = $cat[0];
			if ($cat) {
				$cats = get_category_parents($cat, TRUE, $delimiter);
				$cats = str_replace('<a', $link_before . '<a' . $link_attr, $cats);
				$cats = str_replace('</a>', '</a>' . $link_after, $cats);
				if ($show_title == 0) $cats = preg_replace('/ title="(.*?)"/', '', $cats);
				echo $cats;
			}
			printf($link, get_permalink($parent), $parent->post_title);
			if ($show_current == 1) echo $delimiter . $before . get_the_title() . $after;

		} elseif ( is_page() && !$parent_id ) {
			if ($show_current == 1) echo $before . get_the_title() . $after;

		} elseif ( is_page() && $parent_id ) {
			if ($parent_id != $frontpage_id) {
				$breadcrumbs = array();
				while ($parent_id) {
					$page = get_page($parent_id);
					if ($parent_id != $frontpage_id) {
						$breadcrumbs[] = sprintf($link, get_permalink($page->ID), get_the_title($page->ID));
					}
					$parent_id = $page->post_parent;
				}
				$breadcrumbs = array_reverse($breadcrumbs);
				for ($i = 0; $i < count($breadcrumbs); $i++) {
					echo $breadcrumbs[$i];
					if ($i != count($breadcrumbs)-1) echo $delimiter;
				}
			}
			if ($show_current == 1) {
				if ($show_home_link == 1 || ($parent_id_2 != 0 && $parent_id_2 != $frontpage_id)) echo $delimiter;
				echo $before . get_the_title() . $after;
			}

		} elseif ( is_tag() ) {
			echo $before . sprintf($text['tag'], single_tag_title('', false)) . $after;

		} elseif ( is_author() ) {
	 		global $author;
			$userdata = get_userdata($author);
			echo $before . sprintf($text['author'], $userdata->display_name) . $after;

		} elseif ( is_404() ) {
			echo $before . $text['404'] . $after;

		} elseif ( has_post_format() && !is_singular() ) {
			echo get_post_format_string( get_post_format() );
		}

		if ( get_query_var('paged') ) {
			if ( is_category() || is_day() || is_month() || is_year() || is_search() || is_tag() || is_author() ) echo ' (';
			echo __('Page') . ' ' . get_query_var('paged');
			if ( is_category() || is_day() || is_month() || is_year() || is_search() || is_tag() || is_author() ) echo ')';
		}

		echo '</div><!-- .breadcrumbs -->';

	}
} // end dimox_breadcrumbs()

Gist on GitHub.

Simply paste this function into a functions.php file of your theme and then paste the following code in a place of your theme, where breadcrumbs must appearing:

<?php if (function_exists('dimox_breadcrumbs')) dimox_breadcrumbs(); ?>

All that remains to do for now, is to design your breadcrumbs with CSS. You can use #crumbs for styling breadcrumbs block and #crumbs .current for styling a current crumb.

You can also look at breadcrumbs video tutorial, which show you how to install this function on TwentyTen WordPress theme.

Function works on WordPress 3.0 or higher.

Cоmmеnts (604):
  1. 600
    @
    carlos said:

    Hi,

    Thank you so much for this code.

    I`v read all the comments and try to figure out how to have this:

    home>>CPT>>taxonomy_name>>child_taxonomy_name>>product_name

    Like this:

    Home>>products>>sony>>mp3 player>>MX DVZ

    Is it possible

    Thanks

  2. 601

    Hi Dimox,

    great work. Before I had a few problems with the Breadcrumb NavXT plugin but your code solved my problem. Less plugins – less trouble, thank you for that ;-)

    However, my website is a Multi-site network and I do have one little problem. On the jobs-board landing page page, if you click on a job it looks like that:
    You are here: Home » Job Listing » Early Childhood Teacher – Lismore
    If you want to go back to the parent page (job listings) it goes to an error 404 page or and if you do the same on another site of the website network it goes to http://jobshubnct.org.au/taree/job-applications/

    Could you please have a look?

    Thanks for your help
    Thomas

  3. 602

    Hi,

    Thanks for this great code. I have only one problem and it is when I hover the category link the title is ” View all posts in xxx ” – which xxx is the category name -. My question is how to make the link hover is only the category name? I will appreciate your answer very much.

    Thanks in advance,
    Mansour

    • 603

      Hi,

      Find this row (in 3 places):

      if ($show_title == 0) $cats = preg_replace('/ title="(.*?)"/', '', $cats);

      and paste the following after it:

      $cats = str_replace('View all posts in ', '', $cats);
Соmmеnt раgеs: « 1 10 11 12
Lеаvе а Соmmеnt

© 2009–2014 Dimox.net  •  Privacy Policy