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.

WordPress breadcrumbs function (last updated: 2013.01.04)

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

	$showCurrent = 1; // 1 - show current post/page title in breadcrumbs, 0 - don't show
	$showOnHome  = 0; // 1 - show breadcrumbs on the homepage, 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;
	$homeLink = get_bloginfo('url') . '/';
	$linkBefore = '<span typeof="v:Breadcrumb">';
	$linkAfter = '</span>';
	$linkAttr = ' rel="v:url" property="v:title"';
	$link = $linkBefore . '<a' . $linkAttr . ' href="%1$s">%2$s</a>' . $linkAfter;

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

		if ($showOnHome == 1) echo '<div id="crumbs"><a href="' . $homeLink . '">' . $text['home'] . '</a></div>';

	} else {

		echo '<div id="crumbs" xmlns:v="http://rdf.data-vocabulary.org/#">' . sprintf($link, $homeLink, $text['home']) . $delimiter;

		if ( is_category() ) {
			$thisCat = get_category(get_query_var('cat'), false);
			if ($thisCat->parent != 0) {
				$cats = get_category_parents($thisCat->parent, TRUE, $delimiter);
				$cats = str_replace('<a', $linkBefore . '<a' . $linkAttr, $cats);
				$cats = str_replace('</a>', '</a>' . $linkAfter, $cats);
				echo $cats;
			}
			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, $homeLink . '/' . $slug['slug'] . '/', $post_type->labels->singular_name);
				if ($showCurrent == 1) echo $delimiter . $before . get_the_title() . $after;
			} else {
				$cat = get_the_category(); $cat = $cat[0];
				$cats = get_category_parents($cat, TRUE, $delimiter);
				if ($showCurrent == 0) $cats = preg_replace("#^(.+)$delimiter$#", "$1", $cats);
				$cats = str_replace('<a', $linkBefore . '<a' . $linkAttr, $cats);
				$cats = str_replace('</a>', '</a>' . $linkAfter, $cats);
				echo $cats;
				if ($showCurrent == 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($post->post_parent);
			$cat = get_the_category($parent->ID); $cat = $cat[0];
			$cats = get_category_parents($cat, TRUE, $delimiter);
			$cats = str_replace('<a', $linkBefore . '<a' . $linkAttr, $cats);
			$cats = str_replace('</a>', '</a>' . $linkAfter, $cats);
			echo $cats;
			printf($link, get_permalink($parent), $parent->post_title);
			if ($showCurrent == 1) echo $delimiter . $before . get_the_title() . $after;

		} elseif ( is_page() && !$post->post_parent ) {
			if ($showCurrent == 1) echo $before . get_the_title() . $after;

		} elseif ( is_page() && $post->post_parent ) {
			$parent_id  = $post->post_parent;
			$breadcrumbs = array();
			while ($parent_id) {
				$page = get_page($parent_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 ($showCurrent == 1) echo $delimiter . $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;
		}

		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>';

	}
} // end dimox_breadcrumbs()

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 (525):
  1. 434
    factotum said:

    вариант для категорий, если необходимо добавить микродаты:
    $currentCat = get_category(get_query_var('cat'),false);
    if ($currentCat->category_parent) :
    $parentCats = get_category($currentCat->category_parent);
    echo '<li><a href="' . get_category_link( $parentCats->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $parentCats->name ) . '" >' . $parentCats->name.'</a></li>';
    endif;
    echo '<li>' . $before . single_cat_title('', false) . $after . '</li>';

    PS. В примере парсит только один уровень родительской категории.

  2. 435
    factotum said:

    вывод категорий для постов:
    найти:
    $cat = get_the_category(); $cat = $cat[0];
    $cats = get_category_parents($cat, TRUE, ' ' . $delimiter . ' ');

    заменить на:
    $cat = get_the_category(); $cat = $cat[0];
    if ($cat) :
    $cats = get_category_parents($cat, TRUE, ' ' . $delimiter . ' ');
    endif;

    необходимо в случае, если не задана категория поста. По умолчанию выводится “без категории”, но дебагер выдает ошибку – “$cat не существует”
    Ну конечно же, было бы неплохо увидеть текстовые домены. а их нет ни одного…

  3. 436

    Hi,

    I think you must change, because on some theme and new wordpress version not want to work…

    $homeLink = home_url();

    to

    $homeLink = home_url();

  4. 439

    I would like to change the order of the breadcrumb so that instead of:

    grandparent > parent > child > grandchild

    it would be:

    grandchild < child < parent < grandparent

    Is that possible ?

    Thank you.

  5. 441

    Hey,

    is there a possibility to have a breadcrumb with the Category Base?

    for Categories: Home > Category Base > Category
    for single posts: Home > Category Base > Category > Post

    Regards!

  6. 442

    Hi,

    Love using this. Wondering if there is a possibility of supporting post formats? So for example if we go to “image” post format link, it will show as
    Home > Posts under "image" format
    or something like that.
    Thanks in advance.

  7. 443
    @
    melanie said:

    Hi – Thanks for this code. It is working great for me, except for one little problem with posts.

    When something is tagged with two top-level categories, the breadcrumb includes one of them, apparently chosen randomly (or the first in alpha or category id order?) For example: I have a post with category “News” and category “Kenya” – the breadcrumb shows “Kenya” and ignores “News”. Is there a way to dynamically insert the category based on on referring URL?

    Theme is Vigilance pro, if that matters.

    Thank you!

  8. 445
    @
    Dyadyul said:

    if you want to show parent of custom post type single page
    from this: home > post_type_name > post
    to this: home > post_type_name > post_parent >post

    if ( get_post_type() != 'post' ) {
    $post_type = get_post_type_object(get_post_type());
    $slug = $post_type->rewrite;
    echo '<a href="' . $homeLink . '/' . $slug['slug'] . '/" rel="nofollow">' . $post_type->labels->name . '</a>';
    if ($post->post_parent){
    $ancestors=get_post_ancestors($post->ID);
    $root=count($ancestors)-1;
    $parent = $ancestors[$root];
    echo '<a href="' .get_permalink($parent). '/" rel="nofollow">' . get_the_title($parent) . '</a>';
    };

  9. 446

    First of all, great function! :)

    Is there anyway of getting this to work directly from menus created in:

    dashboard->appearence->menus?

    I create menus this way and it’s duplicate effort if have to then go into each page and select a parent etc.

    Thanks so much

    • 447

      I don’t understood you.

      • 448

        Apologies i will try to be more clear.

        If generate my navigation from wp_nav_menu function. The navigation is created by creating a menu in dashboard->appearance->menus.

        The problem is that when i use your function, it doesn’t match the different levels of the menu here. It will always only give me:

        Home -> Current page

        Even if the actual trail is:

        Home -> Parent -> Child (current page)

        If however i go to:

        Dasboard-Pages->Whatever the current page is

        And i select the page parent here and update the page, the breadcrumb will then display correctly.

        So what I’m saying is if there is anyway I can get around having to do this for every page? Can the function create the breadcrumb based on what I have created in Dashboard->Appearence->Menus without having to specify the parent in Dashboard->pages>the page?

        Hopefully that is clearer :)

        Thanks

  10. 450

    great!!! :)

  11. 451

    Hi Dimox, thanks for the function!

    Im using in my blog, it works but not in all subcategories, i have problems in the breadcrumb subcategory output in the single post view:

    Correct output showing the subcategory Cortometrajes:
    Inicio » Entretenimiento » Cortometrajes » The Gift (2010) de Carl Rinsch

    Incorrect output, missing the subcategory Trailers:
    Inicio » Entretenimiento » ¿? ParaNorman (2012)

    Both posts have published with marked category and subcategory.

    I think the problem is when the first letter of subcategory is low in the abecedari than the first letter of category, in this case the subcategory don’t show, an example on the menu of my blog:

    Cine-TV
    — Películas (DON’T WORK)
    — Series (DON’T WORK)

    Entretenimiento
    — Canciones (WORK)
    — Cortometrajes (WORK)
    — Imágenes (DON’T WORK)
    — Miniseries (DON’T WORK)
    — Programas TV (DON’T WORK)
    — Trailers (DON’T WORK)
    — Videoclips (DON’T WORK)
    — Vídeos (DON’T WORK)

    Do you have any idea of how to fix this?

  12. 452

    sorry, wanted to say when the first letter of category is first in the alphabet than the first letter of subcategory.

  13. 456

    Thankyou for this! Nice and easy.

  14. 457

    I am using buddypress with wordpress and if you click on a specific member’s profile their page does not appear in the breadcrumb. This is the same case for groups and forum. It will remain saying Home >> Members or Home >> Groups. Is there any way to change this?

  15. 459

    Nice job! I appreciate the light-weight, quick block of code. Solved my issue quickly. Thank you for sharing.

  16. 460

    Thanks for the script! A little tweaking for the fact that I always custom-build themes.

  17. 461

    Hi. Love the script, one slight issue, wonder if you can help?.

    On my pages the script works perfectly however once I click on a post, which is categorised under Parent>Child>Post, the breadcrumbs link add in the word category to the links so the breadcrumb links to Home>Category>Parent>Child>Post which doesn’t exist.

    How do I remove the category that gets added in?

    • 462

      I don’t know what’s the reason of that.

    • 480

      I have the same problem. Did you manage to find a solution?

      Anyone have any ideas as to what this could be?

      Playing around with the permalink settings doesn’t help either. It’s strange if I change the ‘category base’ setting in the permalinks dialog, the breadcrumbs category link will point to that change but the page will still not show. Instead I get a blank white page, not even the 404.

      Anyone have any ideas? Desperate to get this to work )-:

      Thanks!

  18. 464

    This tutorial is awesome!!! Thanks!!! works!!!

  19. 465

    :D ~ now it works.

    I forgot that I have created a ‘fullwidth’ template for the ‘Page’ and didn’t add the breadcrumb. No wonder it didn’t show.

    Good code snippet you have there! thanks again! :)

  20. 466

    Very easy to implement, thanks for us un-skilled in php.

    But i’d like to completely remove the Start Home page Home-page1-page1.
    Because i use it in a page already, with a nav menu in place some where else. Should only be used as navigation index on 1 page.

    right now , there is only the option to hide, it buy the seperators will still be placed before the 1st menu item, and that looks ugly.Want it only to be placed after page1- not -page1-
    because there is no menu item before the 1st one…

  21. 467

    Hi, Dimox,

    I’ve combined this “WordPress Breadcrumbs Without a Plugin” function and 3 different CSS3 styles. I’d like to know: What is the license for this work? Am I free to share your code, non-commercial as-is? I am giving credit to you, of course.

    You can see the CSS3/WordPress breadcrumb “mash-up” on my blog here:

    How to Make CSS3 Style WordPress Breadcrumb Navigation

    Thanks,
    Brian

  22. 469

    nice job buddy works pretty fine

  23. 470

    This snippet was not working for the password neither protected ‘Post’ or ‘Page’ until I removed this part:
    } elseif ( is_attachment() ) {
    $parent = get_post($post->post_parent);
    $cat = get_the_category($parent->ID); $cat = $cat[0];
    echo get_category_parents($cat, TRUE, ' ' . $delimiter . ' ');
    echo '' . $parent->post_title . '';
    if ($showCurrent == 1) echo ' ' . $delimiter . ' ' . $before . get_the_title() . $after;

    and replaced it with this:

    } elseif ( !is_single() && !is_page() && get_post_type() != 'post' && post_password_required() ) {
    $parent = get_post($post->post_parent);
    $cat = get_the_category($parent->ID); $cat = $cat[0];
    echo get_category_parents($cat, TRUE, ' ' . $delimiter . ' ');
    echo '' . $parent->post_title . '';
    if ($showCurrent == 1) echo ' ' . $delimiter . ' ' . $before . get_the_title() . $after;

    Now for the password protected ‘Page’ this snippet works just fine.

    But I wonder why for the password protected ‘Post’ this snippet is only showing the image attachment? even after a user entered the password?
    Also It will only display the full content in the homepage and not in the archive page.

    Any clue of how to fix this?

    Thanks!

  24. 471

    Hi Dimox, great code, thank you. Tried to add a function no minimize the title length (in best case everywhere, parents, children AND current title, but don’t get it running, any idea?
    Cheers, gbennyb


    define('BREADCRUMB_TITLE_SIZE', '5');

    function dimox_breadcrumbs() {

    $showOnHome = 0; // 1 - show breadcrumbs on the homepage, 0 - don't show
    //$delimiter = '⇨'; // delimiter between crumbs - TODO pfeil
    $delimiter = '';
    $home = ' '; // text for the 'Home' link
    $showCurrent = 1; // 1 - show current post/page title in breadcrumbs, 0 - don't show
    $before = ''; // tag before the current crumb
    $after = ''; // tag after the current crumb

    global $post;
    $homeLink = get_bloginfo('url');

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

    if ($showOnHome == 1) echo '' . $home . '';

    } else {

    echo '' . $home . ' ' . $delimiter . ' ';

    if ( is_category() ) {
    global $wp_query;
    $cat_obj = $wp_query->get_queried_object();
    $thisCat = $cat_obj->term_id;
    $thisCat = get_category($thisCat);
    $parentCat = get_category($thisCat->parent);
    if(strlen($parentCat->name) > intval(BREADCRUMB_TITLE_SIZE)) {
    $parentCat->name = substr($parentCat->name, 0, intval(BREADCRUMB_TITLE_SIZE)).'...';
    }

    $catTitle = single_cat_title('', false);
    if(strlen($catTitle) > BREADCRUMB_TITLE_SIZE) {
    $catTitle = substr($catTitle, 0, BREADCRUMB_TITLE_SIZE).'...';
    }
    if ($thisCat->parent != 0) echo(get_category_parents($parentCat, TRUE, ' ' . $delimiter . ' '));
    echo $before . '' . $catTitle . '' . $after;

    } elseif ( is_day() ) {
    echo '' . get_the_time('Y') . ' ' . $delimiter . ' ';
    echo '' . get_the_time('F') . ' ' . $delimiter . ' ';
    echo $before . get_the_time('d') . $after;

    } elseif ( is_month() ) {
    echo '' . 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;
    echo '' . $post_type->labels->singular_name . ' ' . $delimiter . ' ';
    if ($showCurrent == 1) echo $before . get_the_title() . $after;
    } else {
    $cat = get_the_category(); $cat = $cat[0];
    echo get_category_parents($cat, TRUE, ' ' . $delimiter . ' ');
    if ($showCurrent == 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($post->post_parent);
    $cat = get_the_category($parent->ID); $cat = $cat[0];
    echo get_category_parents($cat, TRUE, ' ' . $delimiter . ' ');
    echo '' . $parent->post_title . ' ' . $delimiter . ' ';
    if ($showCurrent == 1) echo $before . get_the_title() . $after;

    } elseif ( is_page() && !$post->post_parent ) {
    if ($showCurrent == 1) echo $before . get_the_title() . $after;

    } elseif ( is_page() && $post->post_parent ) {
    $parent_id = $post->post_parent;
    $breadcrumbs = array();
    while ($parent_id) {
    $page = get_page($parent_id);
    $breadcrumbs[] = 'ID) . '">' . get_the_title($page->ID) . '';
    $parent_id = $page->post_parent;
    }
    $breadcrumbs = array_reverse($breadcrumbs);
    foreach ($breadcrumbs as $crumb) echo $crumb . ' ' . $delimiter . ' ';
    if ($showCurrent == 1) echo $before . get_the_title() . $after;

    } elseif ( is_search() ) {
    echo $before . 'Suchergebnisse für "' . get_search_query() . '"' . $after;

    } elseif ( is_tag() ) {
    echo $before . 'Schlagwort "' . single_tag_title('', false) . '"' . $after;

    } elseif ( is_author() ) {
    global $author;
    $userdata = get_userdata($author);
    echo $before . 'Erstellt von ' . $userdata->display_name . $after;

    } elseif ( is_404() ) {
    echo $before . 'Kein passender Inhalt gefunden / Seite nicht gefunden' . $after;
    }

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

    echo '';

    }
    } // end dimox_breadcrumbs()

  25. 472

    Hey,

    Is there a way to display breadcrumbs on a post that contain parent and child page links instead of category links?

    I’m not using Categories. I have custom taxonomies, so I want to use them to create an “if post is in this custom taxonomy, then show this parent and child page breadcrumb”.

    Ex – if “Maytag 3000″ post is in the “Dishwasher” custom taxonomy then I’d want the breadcrumb to be:

    Home >> Appliances >> Dishwasher >> Maytag 3000

    The “Appliances” link goes to the Appliance Page (that I created) and “Dishwashers” link goes to the Dishwasher Page (that I created).

    I’ve been searching everywhere for this and just can’t find it.

    Thanks in advance.

  26. 473

    Hi!
    Beautiful work on this. I’m using a theme where your code is incorporated, and it has a link to this page here.
    I’m wondering, is it possible to display just home » parent » current crumbs, instead of the whole chain? The thing is I don’t need to display the “archives” crumb, just “Home » Portfolio » Graphics” for instance. The original code would display “archives between Home and Portfolio.

  27. 474

    Hi, I’m not using a static page for the blog/posts page. Instead I am using blog.php

    I now find that the breadcrumb link to blog while viewing blog posts doesn’t link back to the actual blog page.

    Home » Blog » Uncategorized » Some Post

    When clicking blog it just links back to the same post instead of blog page.

  28. 475

    Awesome breadcrumbs! This is exactly what I was looking for since I couldn’t find breadcrumbs for PAGES in wordpress, all of them where for posts, but this works awesomely for pages too! Thanks a lot for saving me a lot of time!

  29. 476

    Thank you for your information :D
    finally, I have a breadcrumb

  30. 477

    sorry, forget to ask this question
    “Can i attach your code in my new article (not publish yet) about -”Membuat Breadcrumb Untuk template Wordpress Twenty Twelve”. In Inggris ” How to Make Breadcrumb for Twenty Twelve Wordpress template”?

    I will link to this page as the source of the code. Can I?

Соmmеnt раgеs: « 1 ... 7 8 9 10 »
Lеаvе а Соmmеnt

© 2009–2013 Dimox.net  •  Privacy Policy