Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
WordPress Breadcrumbs Without a Plugin - http://dimox.net/wordpress-breadcrumbs-without-a-plugin/
<?php
/*
* WordPress Breadcrumbs
* author: Dimox
* version: 2017.21.01
* license: MIT
*/
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
$text['page'] = 'Page %s'; // text 'Page N'
$text['cpage'] = 'Comment Page %s'; // text 'Comment Page N'
$wrap_before = '<div class="breadcrumbs" itemscope itemtype="http://schema.org/BreadcrumbList">'; // the opening wrapper tag
$wrap_after = '</div><!-- .breadcrumbs -->'; // the closing wrapper tag
$sep = ''; // separator between crumbs
$sep_before = '<span class="sep">'; // tag before separator
$sep_after = '</span>'; // tag after separator
$show_home_link = 1; // 1 - show the 'Home' link, 0 - don't show
$show_on_home = 0; // 1 - show breadcrumbs on the homepage, 0 - don't show
$show_current = 1; // 1 - show current page title, 0 - don't show
$before = '<span class="current">'; // tag before the current crumb
$after = '</span>'; // tag after the current crumb
/* === END OF OPTIONS === */
global $post;
$home_url = home_url('/');
$link_before = '<span itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">';
$link_after = '</span>';
$link_attr = ' itemprop="item"';
$link_in_before = '<span itemprop="name">';
$link_in_after = '</span>';
$link = $link_before . '<a href="%1$s"' . $link_attr . '>' . $link_in_before . '%2$s' . $link_in_after . '</a>' . $link_after;
$frontpage_id = get_option('page_on_front');
$parent_id = ($post) ? $post->post_parent : '';
$sep = ' ' . $sep_before . $sep . $sep_after . ' ';
$home_link = $link_before . '<a href="' . $home_url . '"' . $link_attr . ' class="home">' . $link_in_before . $text['home'] . $link_in_after . '</a>' . $link_after;
if (is_home() || is_front_page()) {
if ($show_on_home) echo $wrap_before . $home_link . $wrap_after;
} else {
echo $wrap_before;
if ($show_home_link) echo $home_link;
if ( is_category() ) {
$cat = get_category(get_query_var('cat'), false);
if ($cat->parent != 0) {
$cats = get_category_parents($cat->parent, TRUE, $sep);
$cats = preg_replace("#^(.+)$sep$#", "$1", $cats);
$cats = preg_replace('#<a([^>]+)>([^<]+)<\/a>#', $link_before . '<a$1' . $link_attr .'>' . $link_in_before . '$2' . $link_in_after .'</a>' . $link_after, $cats);
if ($show_home_link) echo $sep;
echo $cats;
}
if ( get_query_var('paged') ) {
$cat = $cat->cat_ID;
echo $sep . sprintf($link, get_category_link($cat), get_cat_name($cat)) . $sep . $before . sprintf($text['page'], get_query_var('paged')) . $after;
} else {
if ($show_current) echo $sep . $before . sprintf($text['category'], single_cat_title('', false)) . $after;
}
} elseif ( is_search() ) {
if (have_posts()) {
if ($show_home_link && $show_current) echo $sep;
if ($show_current) echo $before . sprintf($text['search'], get_search_query()) . $after;
} else {
if ($show_home_link) echo $sep;
echo $before . sprintf($text['search'], get_search_query()) . $after;
}
} elseif ( is_day() ) {
if ($show_home_link) echo $sep;
echo sprintf($link, get_year_link(get_the_time('Y')), get_the_time('Y')) . $sep;
echo sprintf($link, get_month_link(get_the_time('Y'), get_the_time('m')), get_the_time('F'));
if ($show_current) echo $sep . $before . get_the_time('d') . $after;
} elseif ( is_month() ) {
if ($show_home_link) echo $sep;
echo sprintf($link, get_year_link(get_the_time('Y')), get_the_time('Y'));
if ($show_current) echo $sep . $before . get_the_time('F') . $after;
} elseif ( is_year() ) {
if ($show_home_link && $show_current) echo $sep;
if ($show_current) echo $before . get_the_time('Y') . $after;
} elseif ( is_single() && !is_attachment() ) {
if ($show_home_link) echo $sep;
if ( get_post_type() != 'post' ) {
$post_type = get_post_type_object(get_post_type());
$slug = $post_type->rewrite;
printf($link, $home_url . $slug['slug'] . '/', $post_type->labels->singular_name);
if ($show_current) echo $sep . $before . get_the_title() . $after;
} else {
$cat = get_the_category(); $cat = $cat[0];
$cats = get_category_parents($cat, TRUE, $sep);
if (!$show_current || get_query_var('cpage')) $cats = preg_replace("#^(.+)$sep$#", "$1", $cats);
$cats = preg_replace('#<a([^>]+)>([^<]+)<\/a>#', $link_before . '<a$1' . $link_attr .'>' . $link_in_before . '$2' . $link_in_after .'</a>' . $link_after, $cats);
echo $cats;
if ( get_query_var('cpage') ) {
echo $sep . sprintf($link, get_permalink(), get_the_title()) . $sep . $before . sprintf($text['cpage'], get_query_var('cpage')) . $after;
} else {
if ($show_current) echo $before . get_the_title() . $after;
}
}
// custom post type
} elseif ( !is_single() && !is_page() && get_post_type() != 'post' && !is_404() ) {
$post_type = get_post_type_object(get_post_type());
if ( get_query_var('paged') ) {
echo $sep . sprintf($link, get_post_type_archive_link($post_type->name), $post_type->label) . $sep . $before . sprintf($text['page'], get_query_var('paged')) . $after;
} else {
if ($show_current) echo $sep . $before . $post_type->label . $after;
}
} elseif ( is_attachment() ) {
if ($show_home_link) echo $sep;
$parent = get_post($parent_id);
$cat = get_the_category($parent->ID); $cat = $cat[0];
if ($cat) {
$cats = get_category_parents($cat, TRUE, $sep);
$cats = preg_replace('#<a([^>]+)>([^<]+)<\/a>#', $link_before . '<a$1' . $link_attr .'>' . $link_in_before . '$2' . $link_in_after .'</a>' . $link_after, $cats);
echo $cats;
}
printf($link, get_permalink($parent), $parent->post_title);
if ($show_current) echo $sep . $before . get_the_title() . $after;
} elseif ( is_page() && !$parent_id ) {
if ($show_current) echo $sep . $before . get_the_title() . $after;
} elseif ( is_page() && $parent_id ) {
if ($show_home_link) echo $sep;
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 $sep;
}
}
if ($show_current) echo $sep . $before . get_the_title() . $after;
} elseif ( is_tag() ) {
if ( get_query_var('paged') ) {
$tag_id = get_queried_object_id();
$tag = get_tag($tag_id);
echo $sep . sprintf($link, get_tag_link($tag_id), $tag->name) . $sep . $before . sprintf($text['page'], get_query_var('paged')) . $after;
} else {
if ($show_current) echo $sep . $before . sprintf($text['tag'], single_tag_title('', false)) . $after;
}
} elseif ( is_author() ) {
global $author;
$author = get_userdata($author);
if ( get_query_var('paged') ) {
if ($show_home_link) echo $sep;
echo sprintf($link, get_author_posts_url($author->ID), $author->display_name) . $sep . $before . sprintf($text['page'], get_query_var('paged')) . $after;
} else {
if ($show_home_link && $show_current) echo $sep;
if ($show_current) echo $before . sprintf($text['author'], $author->display_name) . $after;
}
} elseif ( is_404() ) {
if ($show_home_link && $show_current) echo $sep;
if ($show_current) echo $before . $text['404'] . $after;
} elseif ( has_post_format() && !is_singular() ) {
if ($show_home_link) echo $sep;
echo get_post_format_string( get_post_format() );
}
echo $wrap_after;
}
} // end of dimox_breadcrumbs()

con322 commented Sep 3, 2014

Hey nice work!

Can I use this in a commercial product?

Thanks

jhihaat commented Oct 17, 2014

Hi, I have this error :

Trying to get property of non-object

for this line :

$parent_id = $parent_id_2 = $post->post_parent;

in search results page when the query not found

You may fix the empty search results error (Notice: Tryin to get property of non-object...) by replacing line 40 ($parent_id = $post->post_parent) by the following code:

if (have_posts()) {
    $parent_id = $post->post_parent;
}

Please add support for Woo Commerce & BBPress.

Thanks

ohsik commented Dec 4, 2015

When displaying a post has no category set up will show the error.

Notice: undefined offset:0 on $cat = get_the_category(); $cat = $cat[0];

Catchable fatal error: Object of class WP_Error could not be converted to string in $cats = preg_replace('#<a([^>]+)>([^<]+)<\/a>#', $link_before . '<a$1' . $link_attr .'>' . $link_in_before . '$2' . $link_in_after .'</a>' . $link_after, $cats);

It happened to me also. Please help to fix the error when the post has no category.

jnadd commented Dec 12, 2015

I had a problem trying to condition this:
-- $thisCat = get_category(get_query_var ('cat'), false); --
-- $thisCat->parent != 0 --

The solution for me:
global $wp_query;
$thisCat = $wp_query->queried_object;

kbytin commented Dec 21, 2015

After getting err (Notice: Tryin to get property of non-object...)

changed
$parent_id = $post->post_parent;

to this

$thisPostID = get_the_ID();
$parent_id = wp_get_post_parent_id( $thisPostID );

Can any one tell me I don't want breadcrumb links, it will only text, how to remove the anchor tag from this code

Anydog commented Jun 13, 2016

Yeah, on line 101 and 125 there's an error if post is not assigned to any category (there are some cases):
This
$cat = get_the_category(); $cat = $cat[0];
should be replaced with this (after line 101, for example):

$cat = get_the_category(); 
$cat = isset( $cat ) ? $cat[0] : '';
if( $cat ) {
    $cats = get_category_parents($cat, TRUE, $sep);
    if (!$show_current || get_query_var('cpage')) $cats = preg_replace("#^(.+)$sep$#", "$1", $cats);
    $cats = preg_replace('#<a([^>]+)>([^<]+)<\/a>#', $link_before . '<a$1' . $link_attr .'>' . $link_in_before . '$2' . $link_in_after .'</a>' . $link_after, $cats);
    echo $cats;
    if ( get_query_var('cpage') ) {
        echo $sep . sprintf($link, get_permalink(), get_the_title()) . $sep . $before . sprintf($text['cpage'], get_query_var('cpage')) . $after;
    } else {
        if ($show_current) echo $before . get_the_title() . $after;
    }
}else{
    if ($showCurrent == 1) {
        $breadcrumb_html .= $before . esc_html( strip_tags( get_the_title() ) ) . $after; 
    }
}

Apply the same logic on line 125 (line number will change after line 101 fix)

Maybe can improve this code for custom taxonomy?

I'm using this function to added custom taxonomy on breadcrumb in conditional is_tax(), but i'm don't understand much about php, so is only a suggest :)

function get_taxonomy_parents( $id, $taxonomy = 'category', $link = false, $separator = '/', $nicename = false, $visited = array() ) {

        $chain = '';
        $parent = get_term( $id, $taxonomy );

        if ( is_wp_error( $parent ) )
                return $parent;

        if ( $nicename )
                $name = $parent->slug;
        else
                $name = $parent->name;

        if ( $parent->parent && ( $parent->parent != $parent->term_id ) && !in_array( $parent->parent, $visited ) ) {
                $visited[] = $parent->parent;
                $chain .= get_taxonomy_parents( $parent->parent, $taxonomy, $link, $separator, $nicename, $visited );
        }

        if ( $link )
                $chain .= '<a href="' . esc_url( get_term_link( $parent,$taxonomy ) ) . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $parent->name ) ) . '">'.$name.'</a>' . $separator;
        else
                $chain .= $name.$separator;

        return $chain;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment