Instantly share code, notes, and snippets.
Last active
July 6, 2018 14:51
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save adamdehaven/9ad9809c7574f523e300142c9d60f4da to your computer and use it in GitHub Desktop.
Custom WordPress Breadcrumbs
This file contains hidden or 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 | |
class PW_Breadcrumbs { | |
// Declare variables | |
private $home_link; | |
private $home_text; | |
private $link_before; | |
private $link_after; | |
private $link_attr; | |
private $link; | |
private $delimiter; | |
private $before; | |
private $after; | |
private $page_addon; | |
private $breadcrumb_trail; | |
private $category_links; | |
function __construct() | |
{ | |
// Set variables | |
$this->home_link = site_url('/'); | |
$this->home_text = __( 'Home' ); | |
$this->link_before = '<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">'; | |
$this->link_after = '</li>'; | |
$this->link_attr = ' itemscope itemtype="http://schema.org/Thing" | |
itemprop="item"'; | |
$this->link = $this->link_before . '<a' . $this->link_attr . ' href="%1$s"><span itemprop="name">%2$s</span></a>' . $this->link_after; | |
$this->delimiter = ' <li class="divider">></li> '; // Delimiter between crumbs | |
$this->before = '<li class="current" itemprop="itemListElement" itemscope | |
itemtype="http://schema.org/ListItem"><span itemscope itemtype="http://schema.org/Thing" | |
itemprop="item"><span itemprop="name">'; // Tag before the current crumb | |
$this->after = '</span></span></li>'; // Tag after the current crumb | |
$this->page_addon = ''; // Adds the page number if the query is paged | |
$this->breadcrumb_trail = ''; | |
$this->category_links = ''; | |
} // __construct() | |
public function generate() | |
{ | |
/** | |
* Set our own $wp_the_query variable. Do not use the global variable version due to | |
* reliability | |
*/ | |
$wp_the_query = $GLOBALS['wp_the_query']; | |
$queried_object = $wp_the_query->get_queried_object(); | |
// Handle single post requests which includes single pages, posts and attatchments | |
if ( is_singular() ) | |
{ | |
/** | |
* Set our own $post variable. Do not use the global variable version due to | |
* reliability. We will set $post_object variable to $GLOBALS['wp_the_query'] | |
*/ | |
$post_object = sanitize_post( $queried_object ); | |
// Set variables | |
$title = apply_filters( 'the_title', $post_object->post_title ); | |
$parent = $post_object->post_parent; | |
$post_type = $post_object->post_type; | |
$post_id = $post_object->ID; | |
$post_link = $this->before . $title . $this->after; | |
$parent_string = ''; | |
$post_type_link = ''; | |
if ( 'post' === $post_type ) | |
{ | |
// Get the post categories | |
$categories = get_the_category( $post_id ); | |
if ( $categories ) { | |
// Lets grab the first category | |
$category = $categories[0]; | |
$this->category_links = get_category_parents( $category, true, $this->delimiter ); | |
$this->category_links = str_replace( '<a', $this->link_before . '<a' . $this->link_attr, $this->category_links ); | |
$this->category_links = str_replace( '</a>', '</a>' . $this->link_after, $this->category_links ); | |
} | |
} | |
if ( !in_array( $post_type, ['post', 'page', 'attachment'] ) ) | |
{ | |
$post_type_object = get_post_type_object( $post_type ); | |
$archive_link = esc_url( get_post_type_archive_link( $post_type ) ); | |
$post_type_link = sprintf( $this->link, $archive_link, $post_type_object->labels->singular_name ); | |
} | |
// Get post parents if $parent !== 0 | |
if ( 0 !== $parent ) | |
{ | |
$parent_links = []; | |
while ( $parent ) { | |
$post_parent = get_post( $parent ); | |
$parent_links[] = sprintf( $this->link, esc_url( get_permalink( $post_parent->ID ) ), get_the_title( $post_parent->ID ) ); | |
$parent = $post_parent->post_parent; | |
} | |
$parent_links = array_reverse( $parent_links ); | |
$parent_string = implode( $this->delimiter, $parent_links ); | |
} | |
// Lets build the breadcrumb trail | |
if ( $parent_string ) { | |
$this->breadcrumb_trail = $parent_string . $this->delimiter . $post_link; | |
} else { | |
$this->breadcrumb_trail = $post_link; | |
} | |
if ( $post_type_link ) | |
$this->breadcrumb_trail = $post_type_link . $this->delimiter . $this->breadcrumb_trail; | |
if ( $this->category_links ) | |
$this->breadcrumb_trail = $this->category_links . $this->breadcrumb_trail; | |
} | |
// Handle archives which includes category-, tag-, taxonomy-, date-, custom post type archives and author archives | |
if( is_archive() ) | |
{ | |
if ( is_category() | |
|| is_tag() | |
|| is_tax() | |
) { | |
// Set the variables for this section | |
$term_object = get_term( $queried_object ); | |
$taxonomy = $term_object->taxonomy; | |
$term_id = $term_object->term_id; | |
$term_name = $term_object->name; | |
$term_parent = $term_object->parent; | |
$taxonomy_object = get_taxonomy( $taxonomy ); | |
$current_term_link = $this->before . $taxonomy_object->labels->singular_name . ': ' . $term_name . $this->after; | |
$parent_term_string = ''; | |
if ( 0 !== $term_parent ) | |
{ | |
// Get all the current term ancestors | |
$parent_term_links = []; | |
while ( $term_parent ) { | |
$term = get_term( $term_parent, $taxonomy ); | |
$parent_term_links[] = sprintf( $this->link, esc_url( get_term_link( $term ) ), $term->name ); | |
$term_parent = $term->parent; | |
} | |
$parent_term_links = array_reverse( $parent_term_links ); | |
$parent_term_string = implode( $this->delimiter, $parent_term_links ); | |
} | |
if ( $parent_term_string ) { | |
$this->breadcrumb_trail = $parent_term_string . $this->delimiter . $current_term_link; | |
} else { | |
$this->breadcrumb_trail = $current_term_link; | |
} | |
} elseif ( is_author() ) { | |
$this->breadcrumb_trail = __( 'Author archive for ') . $this->before . $queried_object->data->display_name . $this->after; | |
} elseif ( is_date() ) { | |
// Set default variables | |
$year = $wp_the_query->query_vars['year']; | |
$monthnum = $wp_the_query->query_vars['monthnum']; | |
$day = $wp_the_query->query_vars['day']; | |
// Get the month name if $monthnum has a value | |
if ( $monthnum ) { | |
$date_time = DateTime::createFromFormat( '!m', $monthnum ); | |
$month_name = $date_time->format( 'F' ); | |
} | |
if ( is_year() ) { | |
$this->breadcrumb_trail = $this->before . $year . $this->after; | |
} elseif( is_month() ) { | |
$year_link = sprintf( $this->link, esc_url( get_year_link( $year ) ), $year ); | |
$this->breadcrumb_trail = $year_link . $this->delimiter . $this->before . $month_name . $this->after; | |
} elseif( is_day() ) { | |
$year_link = sprintf( $this->link, esc_url( get_year_link( $year ) ), $year ); | |
$month_link = sprintf( $this->link, esc_url( get_month_link( $year, $monthnum ) ), $month_name ); | |
$this->breadcrumb_trail = $year_link . $this->delimiter . $month_link . $this->delimiter . $this->before . $day . $this->after; | |
} | |
} elseif ( is_post_type_archive() ) { | |
$post_type = $wp_the_query->query_vars['post_type']; | |
$post_type_object = get_post_type_object( $post_type ); | |
$this->breadcrumb_trail = $this->before . $post_type_object->labels->singular_name . $this->after; | |
} | |
} | |
// Handle the search page | |
if ( is_search() ) { | |
$this->breadcrumb_trail = __( 'Search query for: ' ) . $this->before . get_search_query() . $this->after; | |
} | |
// Handle 404's | |
if ( is_404() ) { | |
$this->breadcrumb_trail = $this->before . __( 'Error 404' ) . $this->after; | |
} | |
// Handle paged pages | |
if ( is_paged() ) { | |
$current_page = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : get_query_var( 'page' ); | |
$this->page_addon = $this->before . sprintf( __( ' ( Page %s )' ), number_format_i18n( $current_page ) ) . $this->after; | |
} | |
$breadcrumb_output_link = ''; | |
$breadcrumb_output_link .= '<ol class="awc-breadcrumbs" itemscope itemtype="http://schema.org/BreadcrumbList">'; | |
if ( is_home() || is_front_page() | |
) { | |
// Do not show breadcrumbs on page one of home and frontpage | |
if ( is_paged() || is_home() ) { | |
$breadcrumb_output_link .= '<li itemprop="itemListElement" itemscope | |
itemtype="http://schema.org/ListItem"><a href="' . $this->home_link . '" itemscope itemtype="http://schema.org/Thing" | |
itemprop="item"><span itemprop="name">' . $this->home_text . '</span></a></li>'; | |
$breadcrumb_output_link .= $this->delimiter; | |
if ( is_paged() ) { | |
$breadcrumb_output_link .= '<li itemprop="itemListElement" itemscope | |
itemtype="http://schema.org/ListItem"><a href="' . site_url('/news/') . '" itemscope itemtype="http://schema.org/Thing" | |
itemprop="item"><span itemprop="name">News</span></a></li>'; | |
$breadcrumb_output_link .= $this->page_addon; | |
} else { | |
$breadcrumb_output_link .= '<li class="current" itemprop="itemListElement" itemscope | |
itemtype="http://schema.org/ListItem"><span itemscope itemtype="http://schema.org/Thing" | |
itemprop="item"><span itemprop="name">News</span></span></li>'; | |
} | |
} | |
} else { | |
$breadcrumb_output_link .= '<li itemprop="itemListElement" itemscope | |
itemtype="http://schema.org/ListItem"><a href="' . $this->home_link . '" itemscope itemtype="http://schema.org/Thing" | |
itemprop="item"><span itemprop="name">' . $this->home_text . '</span></a></li>'; | |
$breadcrumb_output_link .= $this->delimiter; | |
$breadcrumb_output_link .= $this->breadcrumb_trail; | |
$breadcrumb_output_link .= $this->page_addon; | |
} | |
$breadcrumb_output_link .= '</ol><!-- .breadcrumbs -->'; | |
return $breadcrumb_output_link; | |
} | |
} // end PW_Breadcrumbs |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment