Instantly share code, notes, and snippets.
Last active
December 22, 2015 08:59
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(1)
1
You must be signed in to fork a gist
-
Save julien731/6448820 to your computer and use it in GitHub Desktop.
Generates a very customizable breadcrumb for WordPress. It supports all kind of content (pages, posts, archives, CPT...).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Generates a breadcrumb for WordPress | |
* | |
* This function will generate a very customizable breadcrumb | |
* for WordPress. It supports all kind of content (pages, posts, | |
* archives, CPT...). | |
* | |
* @author Julien Liabeuf <[email protected]> | |
* @copyright 2013 ThemeAvenue | |
* @package ThemeAvenue Framework | |
* @param (array) $args Breadcrumb parameters | |
* @since 3.0 | |
*/ | |
function tav_breadcrumbs( $args = array() ) { | |
global $post, $wp_query; | |
/* Prepare default arguments */ | |
$defaults = array( | |
'front_page_label' => __( 'Home', 'tav' ), | |
'home_page_label' => __( 'Blog', 'tav' ), | |
'search_results_label' => __( 'Search', 'tav' ), | |
'page_404_label' => __( 'Not Found', 'tav' ), | |
'show_current_page' => true, | |
'link_current_page' => false, | |
'show_on_front' => false, | |
'show_on_home' => true, | |
'link_on_home' => true, | |
'container' => 'div', | |
'container_id' => '', | |
'container_class' => '', | |
'container_attr' => '', | |
'home_url' => home_url(), | |
'item_before' => '', | |
'item_after' => '', | |
'home_before' => false, // If false, item_before will be used instead | |
'home_after' => false, // If false, item_after will be used instead | |
'link_attr' => '', | |
'delimiter' => ' / ' | |
); | |
/** | |
* Let's merge the default settings | |
* with the user defined ones and return | |
* each option in a variable. | |
*/ | |
extract( | |
shortcode_atts( | |
$defaults, | |
$args | |
) | |
); | |
$open = ''; // Breadcrumb opening tag | |
$close = ''; // Breadcrumb closing tag | |
$items = array(); // We will store the items to be imploded later | |
$first = ''; // First item label | |
$home_before = !$home_before ? $item_before : $home_before; | |
$home_after = !$home_after ? $item_after : $home_after; | |
/** | |
* We identify which is the homepage. | |
*/ | |
$home = get_option( 'page_on_front', false ); | |
/** | |
* If the current page is the front page | |
* and breadcrumb is hidden on this page, | |
* we return nothing. | |
*/ | |
if( is_front_page() && !$show_on_front ) { | |
return; | |
} | |
if( is_home() && !$show_on_home ) { | |
return; | |
} | |
/* Open the breadcrumbs container */ | |
$open .= '<' . $container; | |
/* Add the container ID if defined */ | |
if( '' != $container_id ) { | |
$open .= ' id="' . $container_id . '"'; | |
} | |
/* Add the container class if defined */ | |
if( '' != $container_class ) { | |
$open .= ' class="' . $container_class . '"'; | |
} | |
/* Then we close the opening tag */ | |
$open .= '>'; | |
/* Preapare the closing tag. Easy! */ | |
$close .= '</' . $container . '>'; | |
/** | |
* Now we need to prepare the first | |
* item which will depend on the page on front | |
* we identified earlier as $home | |
*/ | |
$first = ( $home ) ? $front_page_label : $home_page_label; | |
/* If the link must be displayed on the first item we add it now */ | |
if( $link_on_home ) { | |
$first = '<a href="' . $home_url . '" class="home" ' . $link_attr . '>' . $first . '</a>'; | |
} | |
/* Add the before and after elements to first item */ | |
$first = $home_before . $first . $home_after; | |
/* The first item is now ready, it's time to add it to the items list */ | |
array_push( $items, $first ); | |
/** | |
* Let's go through the items now... | |
*/ | |
if( is_archive() ) { | |
if( is_tax() ) { | |
if( isset( $wp_query->queried_object ) ) { | |
$item = $wp_query->queried_object->name; | |
$slug = $wp_query->queried_object->slug; | |
/* Get item label to display */ | |
$label = apply_filters( "tav_bc_label_$slug", $wp_query->queried_object->name ); | |
if( $link_current_page ) { | |
$item = '<a href="' . get_term_link( $wp_query->queried_object ) . '" ' . $link_attr . '>' . $label . '</a>'; | |
} | |
$parent_tax = $wp_query->queried_object->parent; // Get parent ID | |
$taxonomy = $wp_query->queried_object->taxonomy; // Get taxonomy | |
$parent_label = array(); // Prepare parents array | |
/* Iterate through parent terms */ | |
for( $ptax = $parent_tax; $ptax != 0; $ptax = $parent_tax ) { | |
$parent_object = get_term( $parent_tax, $taxonomy ); | |
$parent_slug = $parent_object->slug; | |
$label = apply_filters( "tav_bc_label_$parent_slug", $parent_object->name ); | |
$parent_tax = $parent_object->parent; | |
$parent_label[] = array( 'object' => $parent_object, 'label' => $label ); | |
} | |
} | |
} elseif( is_post_type_archive() ) { | |
if( isset( $wp_query->queried_object ) ) { | |
$item = $wp_query->queried_object->label; | |
$slug = $wp_query->queried_object->name; | |
$label = apply_filters( "tav_bc_label_$slug", $wp_query->queried_object->label ); | |
if( $link_current_page ) { | |
$item = '<a href="' . get_post_type_archive_link( $wp_query->queried_object->name ) . '" ' . $link_attr . '>' . $label . '</a>'; | |
} | |
} | |
} | |
} elseif( is_single() ) { | |
$item = esc_html( $post->post_title ); | |
$cats = get_the_category( $post->ID ); | |
$family = array(); | |
$highest = 0; | |
$keep = false; | |
/* If this post has categorie(s) */ | |
if( !empty( $cats ) ) { | |
foreach( $cats as $key => $cat ) { | |
$tax = $cat->taxonomy; | |
$curr_id = $cat->term_id; | |
$parents = array(); | |
while ( $cat->parent != 0 ) { | |
$cat = get_term( $cat->parent, $tax ); | |
$parents[] = $cat; | |
} | |
// $parents = array_reverse( $parents ); | |
$family[$curr_id] = $parents; | |
} | |
if( is_array( $family ) && !empty( $family ) ) { | |
foreach( $family as $ct => $dat ) { | |
$count = count( $dat ); | |
if( $count > $highest ) { | |
$highest = $count; | |
$keep = $ct; | |
} | |
} | |
} | |
if( is_array( $family[$keep] ) && !empty( $family[$keep] ) ) { | |
foreach( $family[$keep] as $categorie => $object ) { | |
$slug = $object->slug; | |
$label = apply_filters( "tav_bc_label_$slug", $object->name ); | |
$parent_label[] = array( 'object' => $object, 'label' => $label ); | |
} | |
} | |
} | |
/* Now let's check if the post is a custom post type */ | |
if( !in_array( $post->post_type, array( 'post', 'page' ) ) ) { | |
$pt = get_post_type_object( $post->post_type ); | |
$link = apply_filters( 'tav_bc_link_parent_' . $post->post_type, get_post_type_archive_link( $post->post_type ) ); | |
$parent_label = '<a href="' . $link . '">' . $pt->label . '</a>'; | |
} | |
} elseif( is_page() ) { | |
/* Ok, we have the page name, easy... */ | |
$item = $post->post_title; | |
/* Current page is the first children */ | |
$upper = $post->post_parent; | |
/* Now let's find all possible parent pages */ | |
for( $i = 0; $upper != 0; $i++ ) { | |
$new_page = get_post( $upper ); | |
$parent_label[] = array( 'id' => $new_page->ID, 'label' => $new_page->post_title ); | |
$upper = $new_page->post_parent; | |
} | |
} elseif( is_404() ) { | |
/* 404 is a very easy case, isn't it? */ | |
$item = $page_404_label; | |
} else { | |
} | |
$item = $item_before . $item . $item_after; | |
/* If there's a parent item let's handle it */ | |
if( isset( $parent_label ) && $parent_label ) { | |
/* In case we have multiple parents, let's add them all */ | |
if( is_array( $parent_label ) ) { | |
/* Normally it goes from children to parents. We want the reverse order. */ | |
$parent_label = array_reverse( $parent_label ); | |
foreach( $parent_label as $key => $parent ) { | |
if( is_single() || is_tax() ) { | |
$link = apply_filters( "tav_bc_link_cat_", get_term_link( $parent['object'] ) ); | |
} elseif( is_page() ) { | |
$link = get_permalink( $parent['id'] ); | |
} else { | |
$link = '#'; | |
} | |
$parent_tmp = $item_before . '<a href="' . $link . '" ' . $link_attr . '>' . $parent['label'] . '</a>' . $item_after; | |
/* Add it to the list */ | |
array_push( $items, $parent_tmp ); | |
} | |
} else { | |
/* Finalize the item */ | |
$parent_label = $item_before . $parent_label . $item_after; | |
/* Add it to the list */ | |
array_push( $items, $parent_label ); | |
} | |
/* Reset parent */ | |
$parent_label = false; | |
} | |
/* Now we can add the (child) item */ | |
array_push( $items, $item ); | |
/** | |
* Now that all items are ready, it's time | |
* to merge them all and add the delimiter | |
* between all of them. | |
*/ | |
$items = implode( $delimiter, $items ); | |
/** | |
* SHOW TIME! | |
* We now echo all the markup. First the opening tag | |
* we prepared at the begining of the function, then | |
* the items we just imploded, and finally | |
* the closing tag. | |
*/ | |
echo $open . $items . $close; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment