Instantly share code, notes, and snippets.
Created
November 27, 2016 12:39
-
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 Antonimo/d930a2a60e468b4c8f4bcafc7465e135 to your computer and use it in GitHub Desktop.
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 | |
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