Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save franz-josef-kaiser/10430735 to your computer and use it in GitHub Desktop.
Save franz-josef-kaiser/10430735 to your computer and use it in GitHub Desktop.
This is a fork of Chip Bennets idea to implement breadcrumbs into WP Core. The code is procedural and really not the best - but it would fit into core much easier this way as when implementing it with real OOP patterns.
<?php
/**
* Add navigation breadcrumb
*/
function wp_nav_breadcrumb() {
// Separator between breadcrumb links
$delimiter = apply_filters( 'wp_nav_breadcrumb_delimiter', ' &raquo; ' );
// Show taxonomy crumbs for single posts
$show_tax_crumb_for_single = apply_filters( 'wp_nav_breadcrumb_show_tax_crumb_for_single', true );
$pagination = false;
// Base link
$baselink = sprintf(
'<a href="%s">%s</a>',
home_url( '/' ),
apply_filters( 'wp_nav_breadcrumb_home_text', __( 'Home' ) )
);
$hierarchy = $delimiter;
// Base link
if ( is_front_page() ) {
$context = wp_nav_breadcrumb_front_page( $base_link );
}
// Define current location for 404 Error page
if ( is_404() ) {
$context = wp_nav_breadcrumb_404();
}
// Define current location for Search Results page
elseif ( is_search() ) {
$context = wp_nav_breadcrumb_search( $delimiter );
}
// Define current location for the blog posts index
elseif ( is_home() && ( 'page' == get_option( 'show_on_front' ) ) ) {
$context = wp_nav_breadcrumb_blog();
}
// Define current location for archive pages
elseif( is_archive() ) {
// Define Category Hierarchy Crumbs for Category Archive
if ( is_category() ) {
$context = wp_nav_breadcrumb_category( $delimiter );
}
// Define current location for Tag Archives
elseif ( is_tag() ) {
$context = wp_nav_breadcrumb_tag( $delimiter );
}
// Define current location for Post Format Archives
elseif ( get_post_format() && ! is_home() ) {
$context = wp_nav_breadcrumb_post_format( $delimiter );
}
// Define current location for Custom Taxonomy Archives
elseif ( is_tax() ) {
$context = wp_nav_breadcrumb_tax( $delimiter );
}
// Define current location for Author Archives
elseif ( is_author() ) {
$context = wp_nav_breadcrumb_author( $delimiter );
}
// Define Crumbs for Day/Year/Month Date-based Archives
elseif ( is_date() ) {
$context = wp_nav_breadcrumb_date( $delimiter );
}
// Define current location for Custom Post Type Archives
elseif ( is_post_type_archive( get_post_type() ) ) {
$context = wp_nav_breadcrumb_post_type_archive( $delimiter );
}
// Define pagination for paged Archive pages
if ( get_query_var( 'paged' ) ) {
$pagination = $delimiter;
$pagination .= apply_filters( 'wp_nav_breadcrumb_paged_archive_text', sprintf( 'Page %s', get_query_var( 'paged' ) ) );
}
}
// Define current location for singular pages
elseif ( is_singular() ) {
if ( is_page() && ! is_front_page() ) {
$context = wp_nav_breadcrumb_page( $delimiter, $show_tax_crumb_for_single );
}
// Define Category and Parent Post Crumbs for Post Attachments
elseif ( is_attachment() ) {
$context = wp_nav_breadcrumb_attachment( $delimiter, $show_tax_crumb_for_single );
}
// Define Category Hierarchy Crumbs for Single Posts
elseif ( is_singular( 'post' ) ) {
$context = wp_nav_breadcrumb_single_blog_post( $delimiter, $show_tax_crumb_for_single );
}
// Define current location for Custom Post Types
elseif ( is_singular( get_post_type() ) ) {
$context = wp_nav_breadcrumb_single_post_type( $delimiter, $show_tax_crumb_for_single );
}
// Define pagination for singular pages
if ( get_query_var( 'page' ) ) {
$pagination = $delimiter;
$pagination .= apply_filters( 'wp_nav_breadcrumb_paged_post_text', sprintf( 'Page %s', get_query_var( 'page' ) ) );
}
}
// Breadcrumb array
$breadcrumb = array();
// Opening element that wraps entire breadcrumb output
$breadcrumb[] = apply_filters( 'wp_nav_breadcrumb_container_before', '<div id="breadcrumbs">' );
// Opening breadcrumb element
$breadcrumb[] = apply_filters( 'wp_nav_breadcrumb_container_open', '<nav class="crumbs">' );
if ( $baselink ) {
$breadcrumb[] = $baselink;
}
if ( $context['hierarchy'] ) {
$breadcrumb[] = $context['hierarchy'];
}
// Opening element that wraps the current page breadcrumb link
$breadcrumb[] = apply_filters( 'wp_nav_breadcrumb_current_before', '<strong>' );
// Current location
$breadcrumb[] = $context['current_location'];
//Closing element that wraps the current page breadcrumb link
$breadcrumb[] = apply_filters( 'wp_nav_breadcrumb_current_after', '</strong>' );
if ( $pagination ) {
$breadcrumb[] = $pagination;
}
// Closing element that wraps entire breadcrumb output
$breadcrumb[] = apply_filters( 'wp_nav_breadcrumb_container_after', '</div>' );
// Closing breadcrumb element
$breadcrumb[] = apply_filters( 'wp_nav_breadcrumb_container_close', '</nav>' );
// Output the result
echo implode( '', apply_filters( 'wp_nav_breadcrumb', $breadcrumb ) );
}
/**
* Site Front Page navigation breadcrumb
*/
function wp_nav_breadcrumb_front_page( $base_link ) {
return array(
'hierarchy' => false,
'current_location' => $base_link
);
}
/**
* 404 navigation breadcrumb
*/
function wp_nav_breadcrumb_404() {
return array(
'hierarchy' => false,
'current_location' => apply_filters( 'wp_nav_breadcrumb_404_text', __( 'Page Not Found' ) )
);
}
/**
* Search results navigation breadcrumb
*/
function wp_nav_breadcrumb_search( $delimiter ) {
$hierarchy = apply_filters( 'wp_nav_breadcrumb_search_text', __( 'Search Results:' ) );
$hierarchy .= $delimiter;
return array(
'hierarchy' => $hierarchy,
'current_location' => get_search_query()
);
}
/**
* Blog posts index navigation breadcrumb
*/
function wp_nav_breadcrumb_blog( $blog_text ) {
// Text for the 'Blog' link
$blog_text = apply_filters( 'wp_nav_breadcrumb_blog_text', __( 'Blog' ) );
if ( is_paged() ) {
$blog_text = sprintf(
'<a href="%s">%s</a>',
get_permalink( get_option( 'page_for_posts' ) ),
$blog_text
);
}
return array(
'hierarchy' => false,
'current_location' => $blog_text
);
}
/**
* Category archive index navigation breadcrumb
*/
function wp_nav_breadcrumb_category( $delimiter ) {
global $wp_query;
$cat_obj = $wp_query->get_queried_object();
$current_cat = $cat_obj->term_id;
$current_cat = get_category( $thisCat );
$hierarchy = apply_filters( 'wp_nav_breadbrumb_category_archive_text', __( 'Category Archive' ) );
$hierarchy .= $delimiter;
if ( $thisCat->parent != 0 ) {
$hierarchy .= get_category_parents( get_category( $current_cat->parent ), true, $delimiter );
}
return array(
'hierarchy' => $hierarchy,
'current_location' => single_cat_title( '' , false )
);
}
/**
* Tag archive index navigation breadcrumb
*/
function wp_nav_breadcrumb_tag( $delimiter ) {
$hierarchy = apply_filters( 'wp_nav_breadcrumb_tag_archive_text', __( 'Tag Archive' ) );
$hierarchy .= $delimiter;
return array(
'hierarchy' => ,
'current_location' => single_tag_title( '' , false )
);
}
/**
* Post Format archive index navigation breadcrumb
*/
function wp_nav_breadcrumb_post_format( $delimiter ) {
$hierarchy = apply_filters( 'wp_nav_breadcrumb_post_format_archive_text', __( 'Post Format Archive' ) );
$hierarchy .= $delmiter;
return array(
'hierarchy' => $hierarchy,
'current_location' => get_post_format_string( get_post_format() )
);
}
/**
* Custom Taxonomy archive index navigation breadcrumb
*/
function wp_nav_breadcrumb_tax( $delimiter ) {
global $wp_query;
$post_type_object = get_post_type_object( get_post_type() );
$post_type_name = $post_type_object->labels->name;
$post_type_slug = $post_type_object->name;
$custom_tax = $wp_query->query_vars['taxonomy'];
$custom_tax_object = get_taxonomy( $custom_tax );
$hierarchy = sprintf(
'<a href="%s">%s</a>',
get_post_type_archive_link( $post_type_slug ),
$post_type_name
);
$hierarchy .= $delimiter;
$hierarchy .= apply_filters( 'wp_nav_breadcrumb_taxonomy_archive_text', __( 'Archive Index for' ) );
$hierarchy .= $delimiter;
return array(
'hierarchy' => $hierarchy,
'current_location' => single_term_title( '', false );
);
}
/**
* Author archive index navigation breadcrumb
*/
function wp_nav_breadcrumb_author( $delimiter ) {
$hierarchy = apply_filters( 'wp_nav_breadcrumb_author_archive_text', __( 'Posts Written by' ) );
$hierarchy .= $delimiter;
return array(
'hierarchy' => $hierarchy,
'current_location' => get_the_author_meta( 'display_name', get_query_var( 'author' ) )
);
}
/**
* Date archive index navigation breadcrumb
*/
function wp_nav_breadcrumb_date( $delimiter ) {
// Define Year/Month Hierarchy Crumbs for Day Archive
if ( is_day() ) {
$date_string = sprintf(
'<a href="%s">%s</a> ',
get_year_link( get_the_time( 'Y' ) ),
get_the_time( 'Y' )
);
$date_string .= $delimiter . ' ';
$date_string .= sprintf(
'<a href="%s">%s</a> ',
get_month_link( get_the_time( 'Y' ), get_the_time( 'm' ) ),
get_the_time( 'F' )
);
$date_string .= $delimiter . ' ';
$current_location = get_the_time('d');
}
// Define Year Hierarchy Crumb for Month Archive
elseif ( is_month() ) {
$date_string = sprintf(
'<a href="%s">%s</a> ',
get_year_link( get_the_time( 'Y' ) ),
get_the_time( 'Y' )
);
$date_string .= $delimiter . ' ';
$current_location = get_the_time( 'F' );
}
// Set CurrentLocation for Year Archive
elseif ( is_year() ) {
$date_string = '';
$current_location = get_the_time( 'Y' );
}
$hierarchy = sprintf( __( 'Posts Published in: %s' ), $date_string );
return array(
'hierarchy' => apply_filters( 'wp_nav_breadcrumb_date_archive_text', $hierarchy ),
'current_location' => $current_location
);
}
/**
* Custom post type archive index breadcrumb
*/
function wp_nav_breadcrumb_post_type_archive( $delimiter ) {
$post_type_object = get_post_type_object( get_post_type() );
$post_type_name = $post_type_object->labels->name;
$hierarchy = apply_filters( 'wp_nav_breadcrumb_post_type_archive_text', __( 'Archive Index for' ) );
$hierarchy .= $delimiter;
return array(
'hierarchy' => $hierarchy,
'current_location' => $post_type_name
);
}
/**
* Static page navigation breadcrumb
*/
function wp_nav_breadcrumb_page( $delimiter ) {
global $post;
// Define Parent Page Hierarchy Crumbs for Hierarchical Pages
if ( $post->post_parent ) {
$parent_id = $post->post_parent;
$pagecrumbs = array();
while ( $parent_id ) {
$page = get_page( $parent_id );
$pagecrumbs[] = sprintf(
'<a href="%s">%s</a>',
get_permalink( $page->ID ),
get_the_title( $page->ID )
);
$parent_id = $page->post_parent;
}
$pagecrumbs = array_reverse( $pagecrumbs );
foreach ( $pagecrumbs as $crumb ) {
$hierarchy .= $crumb;
$hierarchy .= $delimiter;
}
}
return array(
'hierarchy' => $hierarchy,
'current_location' => get_the_title()
);
}
/**
* Attachment page navigation breadcrumb
*/
function wp_nav_breadcrumb_attachment( $delimiter, $show_tax_crumb_for_single ) {
global $post;
$hierarchy = '';
// Get tax crumb
if ( $show_tax_crumb_for_single ) {
$cat_parents = '';
$parent = get_post( $post->post_parent );
if ( get_the_category( $parent->ID ) ) {
$cat = get_the_category( $parent->ID );
$cat_parents = get_category_parents( $cat[0], TRUE, $delimiter );
}
$hierarchy .= $cat_parents;
}
// Get parent post
$hierarchy .= sprintf(
'<a href="%s">%s</a> ',
get_permalink( $parent ),
$parent->post_title
);
$hierarchy .= $delimiter;
return array(
'hierarchy' => $hierarchy,
'current_location' => get_the_title()
);
}
/**
* Single blog post navigation breadcrumb
*/
function wp_nav_breadcrumb_single_blog_post( $delimiter, $show_tax_crumb_for_single ) {
$hierarchy = '';
if ( $show_tax_crumb_for_single ) {
$cats = get_the_category();
// Assume the first category is current
$current_cat = ( $cats ? $cats[0] : '' );
// Determine if category is hierarchical
$cat_is_hierarchical = false;
foreach ( $cats as $cat ) {
if ( '0' != $cat->parent ) {
$cat_is_hierarchical = true;
break;
}
}
// If category is hierarchical,
// ensure we have the correct child category
if ( $cat_is_hierarchical ) {
foreach ( $cats as $cat ) {
$children = get_categories( array( 'parent' => $cat->term_id ) );
if ( 0 == count( $children ) ) {
$current_cat = $cat;
break;
}
}
}
// Get the hierarchical list of category links
$hierarchy .= get_category_parents( $current_cat, TRUE, $delimiter );
}
return array(
'hierarchy' => $hierarchy,
'current_location' => get_the_title()
);
}
/**
* Single custom post navigation breadcrumb
*/
function wp_nav_breadcrumb_single_post_type( $delimiter, $show_tax_crumb_for_single ) {
$hierarchy = '';
$post_type_object = get_post_type_object( get_post_type() );
$post_type_name = $post_type_object->labels->name;
$post_type_slug = $post_type_object->name;
if ( $show_tax_crumb_for_single ) {
$taxonomies = get_object_taxonomies( get_post_type() );
$taxonomy = ( ! empty( $taxonomies ) ? $taxonomies[0] : false );
$terms = ( $taxonomy ? get_the_term_list( $post->ID, $taxonomy ) : false );
if ( $terms ) {
$hierarchy .= $terms;
$hierarchy .= $delimiter;
}
}
$hierarchy .= sprintf(
'<a href="%s">%s</a>',
get_post_type_archive_link( $post_type_slug ),
$post_type_name
);
return array(
'hierarchy' => $hierarchy,
'current_location' => get_the_title()
);
}
  1. consistent naming scheme for functions: wp_nav_menu() > wp_nav_breadcrumbs_*()
  2. array() alignment for better readability on returns. fixed a typo with a missing $hierarchy value for wp_nav_breadcrumb_single_post_type() and removed typo with ; semicolon in the hierarchy return array of wp_nav_breadcrumb_author()
  3. Added _nav to all filter names so they don't differentiate too much from the function names - easier to remember.
  4. Added another forgotten _nav for the delimiter filter name.
  5. Removed massive concatenating of strings. Reduced to bit-by-bit concatenation: One argument per line. Fixed an errornous semicolon on line 202. Changed CamelCased vars like $currentLocation to $current_location. Removed some unnecessary line breaks and moved global always to the beginning of a function. Removed oenology textdomain from ~334
  6. Fixed a comparisson error on L#91: & vs. &&
  7. Removed another camelCase as well as lowercased all booleans.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment