Skip to content

Instantly share code, notes, and snippets.

@Antonimo
Created November 27, 2016 12:39
Show Gist options
  • Save Antonimo/d930a2a60e468b4c8f4bcafc7465e135 to your computer and use it in GitHub Desktop.
Save Antonimo/d930a2a60e468b4c8f4bcafc7465e135 to your computer and use it in GitHub Desktop.
<?php
class CustomMenuBreadcrumbs {
public $menu_location = '';
public $menu = false;
public $menu_items = array();
public function __construct( $menu_location = '' ) {
$this->menu_location = $menu_location;
// for convenience everything is built on Menu location (e.g. user changes out an entire Menu)
$menu_locations = get_nav_menu_locations();
// make sure the location exists
if ( isset( $menu_locations[ $this->menu_location ] ) ) {
$this->menu = wp_get_nav_menu_object( $menu_locations[ $this->menu_location ] );
$this->menu_items = wp_get_nav_menu_items( $this->menu->term_id );
}
}
/**
* Format a URL such that we can compare it easily. Escapes, removes protocol, and removes trailing slash
*
* @since 1.0.0
* @param string $url URL to format
* @return mixed|string Formatted URL (no protocol or trailing slash)
*/
public function format_url( $url = '' ) {
$url = esc_url( $url );
$url = str_replace( array( 'http://', 'https://' ), '', strtolower( $url ) );
$url = rtrim( $url, '/' );
return $url;
}
/**
* Check to see if the page being viewed matches the submitted URL. Requires that we're viewing a WordPress permalink.
*
* @since 1.0.0
* @param string $url The URL to check against the current URL
* @return bool Whether we are viewing the submitted URL
*/
public function is_at_url( $url = '' ) {
global $post;
if ( empty( $url ) ) {
return false;
}
$url = $this->format_url( $url );
$current_url = $this->format_url( get_permalink( $post->ID ) );
return $current_url == $url;
}
/**
* Retrieve the current Menu item object for the current Menu.
*
* @since 1.0.0
* @return bool|WP_Post The current Menu item
*/
public function get_current_menu_item_object() {
$current_menu_item = false;
if ( empty( $this->menu_items ) ) {
return $current_menu_item;
}
// loop through the entire nav menu and determine whether any have a class="current" or are the current URL (e.g. a Custom Link was used)
foreach ( $this->menu_items as $menu_item ) {
// if WordPress was able to detect the current page
if ( is_array( $menu_item->classes ) && in_array( 'current', $menu_item->classes ) ) {
$current_menu_item = $menu_item;
}
// if the current URL matches a Custom Link
if ( ! $current_menu_item && isset( $menu_item->url ) && $this->is_at_url( $menu_item->url ) ) {
$current_menu_item = $menu_item;
}
if ( $current_menu_item ) {
break;
}
}
return $current_menu_item;
}
/**
* Retrieve the current Menu item object's parent Menu item object
*
* @since 1.0.0
* @param WP_Post $current_menu_item The current Menu item object
* @return bool|WP_post The parent Menu object
*/
public function get_parent_menu_item_object( $current_menu_item ) {
$parent_menu_item = false;
if ( empty( $this->menu_items ) ) {
return $current_menu_item;
}
foreach ( $this->menu_items as $menu_item ) {
if ( absint( $current_menu_item->menu_item_parent ) == absint( $menu_item->ID ) ) {
$parent_menu_item = $menu_item;
break;
}
}
return $parent_menu_item;
}
/**
* Generate an array of WP_Post objects that constitutes a breadcrumb trail based on a Menu
*
* @since 1.0.0
* @return array|string Breadcrumb of WP_Post objects
*/
public function generate_trail() {
$current_menu_item = $this->get_current_menu_item_object();
if ( empty( $current_menu_item ) ) {
return '';
}
// there's at least one level
$breadcrumb = array( $current_menu_item );
// work backwards from the current menu item all the way to the top
while ( $current_menu_item = $this->get_parent_menu_item_object( $current_menu_item ) ) {
$breadcrumb[] = $current_menu_item;
}
// since we worked backwards, we need to reverse everything
$breadcrumb = array_reverse( $breadcrumb );
// add a level for each breadcrumb object
$i = 1;
foreach ( $breadcrumb as $key => $val ) {
if ( ! isset( $val->menu_breadcrumb_level ) ) {
$val->menu_breadcrumb_level = $i;
$breadcrumb[ $key ] = $val;
}
$i++;
}
array_pop( $breadcrumb );
return $breadcrumb;
}
}
function add_menu_breadcrumbs( $crumbs ){
// dump( $crumbs );
$menu_breadcrumbs = new CustomMenuBreadcrumbs( 'primary_menu' );
$breadcrumbs = $menu_breadcrumbs->generate_trail();
if ( empty( $breadcrumbs ) ) {
return $crumbs;
}
$last_crumb = array_pop( $crumbs );
foreach ( $breadcrumbs as $key => $breadcrumb ) {
$_url = $breadcrumb->url;
if( $_url == '#' ) $_url = '';
$crumbs[] = array(
'text' => $breadcrumb->title,
'url' => $_url,
'allow_html' => false,
);
}
$crumbs[] = $last_crumb;
return $crumbs;
}
add_filter( 'wpseo_breadcrumb_links', 'add_menu_breadcrumbs', 10, 1 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment