Usage
nebula()->breadcrumbs($options)
Parameters
$options
(Optional) (Array) An array of options
Default: None
Parameter Notes
Options
delimiter
The string between nodes.
Default: /
home
Text for the home link
Default: get_bloginfo('title')
home_link
The URL for the home link
Default: home_url('/')
prefix
What type of prefix to use before certain post types (categories, tags, etc.). Ex: text, icons, off (or false)
Default: text
current
Show or hide the current title in the breadcrumb
Default: true
before
Tag before the current node
Default: <span class="current">
after
Tag after the current crumb
Default: </span>
force
Override the breadcrumbs with an array of specific links (See example below)
Default: false
Examples
Simple Implementation
<?php nebula()->breadcrumbs(); ?>
Replace the delimiter and home link with text
<?php nebula()->breadcrumbs(array('delimiter' => '»', 'home' => '<i class="fas fa-home"></i>')); ?>
Replace the delimiter and home text, and also manually control the nodes. Notice the current page is not passed in the 'force' option; it is controlled by the 'current' option which defaults to true (so it is not passed here).
<?php nebula()->breadcrumbs(array( 'home' => '<i class="fas fa-home"></i>', 'delimiter' => '»', 'force' => array( array('Home', home_url()), array(get_the_title(127), get_permalink(127)), array(get_field('product_type'), get_permalink(get_page_by_title(get_field('product_type')))), ), )); ?>
Disable prefixes for categories and tags
<?php nebula()->breadcrumbs(array('prefix' => false)); ?>
Change settings globally by changing default parameters across the entire site
<?php //Add this to a functions file add_filter('nebula_breadcrumb_defaults', function($defaults){ $defaults['delimiter'] = '›'; $defaults['home'] = '<i class="fas fa-home"></i>'; return $defaults; }); //Now it can be called in template files without parameters: nebula()->breadcrumbs(); ?>
Source File
Located in /libs/Functions.php on line 1391.
7 Hooks
Find these filters and actions in the source code below to hook into them. Use do_action() and add_filter() in your functions file or plugin.
Filters
"pre_nebula_breadcrumbs""nebula_breadcrumb_defaults"
"nebula_breadcrumbs_category"
"nebula_breadcrumbs_tag"
"nebula_breadcrumbs_author"
"nebula_breadcrumbs_error"
"nebula_breadcrumbs_paged"
Need a new filter hook? Request one here.
Actions
This function has no action hooks available. Request one?Note: This function contains 4 to-do comments.
public function breadcrumbs($options=array()){ $override = apply_filters('pre_nebula_breadcrumbs', null); if ( isset($override) ){return;} $this->timer('Breadcrumbs'); global $post; $defaults = apply_filters('nebula_breadcrumb_defaults', array( 'delimiter' => '/', //Delimiter between crumbs 'home' => get_bloginfo('title'), //Text for the 'Home' link 'home_link' => home_url('/'), 'prefix' => 'off', //Prefix categories and tags with "text", "icon", or none with "off" (default) 'current' => true, //Show/Hide the current title in the breadcrumb 'before' => '<li class="current" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">', //Tag before the current crumb 'after' => '</li>', //Tag after the current crumb 'force' => false //Override the breadcrumbs with an array of specific links )); $data = array_merge($defaults, $options); $data['delimiter_html'] = '<li class="delimiter">' . $data['delimiter'] . '</li>'; $data['current_node'] = $data['before'] . '<a class="current-breadcrumb-link" href="' . get_the_permalink() . '" itemprop="item"><span itemprop="name">' . strip_tags(get_the_title()) . '</span></a>'; $position = 1; //Incrementer for each node (for schema tags) if ( !empty($data['force']) ){ //If using forced override echo '<ol class="nebula-breadcrumbs" itemscope itemtype="http://schema.org/BreadcrumbList">'; foreach ( $data['force'] as $node ){ $node_text = ( !empty($node['text']) )? $node['text'] : $node[0]; $node_url = false; if ( !empty($node['url']) ){ $node_url = $node['url']; } else { if ( !empty($node[1]) ){ $node_url = $node[1]; } } if ( !empty($node_text) ){ if ( !empty($node_url) ){ echo '<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="' . $node_url . '" itemprop="item">'; } echo '<span itemprop="name">' . $node_text . '</span>'; if ( !empty($node_url) ){ echo '</a><meta itemprop="position" content="' . $position . '" /></li>'; } echo ' ' . $data['delimiter_html'] . ' '; } $position++; } if ( !empty($data['current']) ){ echo $data['current_node'] . '<meta itemprop="position" content="' . $position . '" />' . $data['after']; } echo '</ol>'; } elseif ( is_home() || is_front_page() ){ echo '<ol class="nebula-breadcrumbs" itemscope itemtype="http://schema.org/BreadcrumbList"><li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="' . $data['home_link'] . '" itemprop="item"><span itemprop="name">' . $data['home'] . ' <span class="visually-hidden">' . get_bloginfo('title') . '</span></span></a><meta itemprop="position" content="' . $position . '" /></li></ol>'; $position++; return false; } else { echo '<ol class="nebula-breadcrumbs" itemscope itemtype="http://schema.org/BreadcrumbList"><li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="' . $data['home_link'] . '" itemprop="item"><span itemprop="name">' . $data['home'] . ' <span class="visually-hidden">' . get_bloginfo('title') . '</span></span></a><meta itemprop="position" content="' . $position . '" /></li> ' . $data['delimiter_html'] . ' '; $position++; if ( is_category() ){ $thisCat = get_category(get_query_var('cat'), false); if ( $thisCat->parent !== 0 ){ $parents = get_ancestors($thisCat->parent, 'category', 'taxonomy'); array_unshift($parents, $thisCat->parent); foreach ( array_reverse($parents) as $term_id ){ $parent = get_term($term_id, 'category'); echo '<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="' . esc_url(get_term_link($parent->term_id, 'category')) . '" itemprop="item"><span itemprop="name">' . $parent->name . '</span></a><meta itemprop="position" content="' . $position . '" /></li> ' . $data['delimiter_html'] . ' '; $position++; } } $prefix = ''; if ( $data['prefix'] === 'icon' ){ $prefix = '<i class="fa-solid fa-bookmark"></i>'; } elseif ( $data['prefix'] === 'text' ){ $prefix = 'Category: '; } echo apply_filters('nebula_breadcrumbs_category', $data['before'] . '<a class="current-breadcrumb-link" href="' . get_category_link($thisCat->term_id) . '" itemprop="item"><span itemprop="name">' . $prefix . single_cat_title('', false) . '</span></a><meta itemprop="position" content="' . $position . '" />' . $data['after'], $data); $position++; } elseif ( is_search() ){ echo $data['before'] . 'Search results' . $data['after']; } elseif ( is_day() ){ echo '<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="' . get_year_link(get_the_time('Y')) . '" itemprop="item"><span itemprop="name">' . get_the_time('Y') . '</span></a><meta itemprop="position" content="' . $position . '" /></li> ' . $data['delimiter_html'] . ' '; $position++; echo '<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="' . get_month_link(get_the_time('Y'), get_the_time('m')) . '" itemprop="item"><span itemprop="name">' . get_the_time('F') . '</span></a><meta itemprop="position" content="' . $position . '" /></li> ' . $data['delimiter_html'] . ' '; $position++; echo $data['before'] . get_the_time('d') . $data['after']; } elseif ( is_month() ){ echo '<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="' . get_year_link(get_the_time('Y')) . '" itemprop="item"><span itemprop="name">' . get_the_time('Y') . '</span></a><meta itemprop="position" content="' . $position . '" /></li> ' . $data['delimiter_html'] . ' '; $position++; echo $data['before'] . get_the_time('F') . $data['after']; } elseif ( is_year() ){ echo $data['before'] . get_the_time('Y') . $data['after']; } elseif ( is_single() && !is_attachment() ){ if ( get_post_type() !== 'post' ){ //Custom Post Type $post_type = get_post_type_object(get_post_type()); $slug = $post_type->rewrite; if ( is_string($post_type->has_archive) ){ //If the post type has a custom archive slug $slug['slug'] = $post_type->has_archive; //Replace slug with the custom archive slug string } echo '<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="' . $data['home_link'] . $slug['slug'] . '/" itemprop="item"><span itemprop="name">' . $post_type->labels->name . '</span></a><meta itemprop="position" content="' . $position . '" /></li>'; //Changed from singular_name so plurals would appear in breadcrumb nodes $position++; //Check for parent "pages" on the custom post type and output them if they exist $parent_id = $post->post_parent; if ( !empty($parent_id) ){ echo $data['delimiter_html']; $breadcrumbs = array(); while ( $parent_id ){ $page = get_page($parent_id); $breadcrumbs[] = '<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="' . get_permalink($page->ID) . '" itemprop="item"><span itemprop="name">' . strip_tags(get_the_title($page->ID)) . '</span></a><meta itemprop="position" content="' . $position . '" /></li>'; $position++; $parent_id = $page->post_parent; } $breadcrumbs = array_reverse($breadcrumbs); $breadcrumbs_nodes = count($breadcrumbs); for ( $i = 0; $i < $breadcrumbs_nodes; $i++ ){ echo $breadcrumbs[$i]; if ( $i !== $breadcrumbs_nodes-1 ){ echo ' ' . $data['delimiter_html'] . ' '; } } } if ( !empty($data['current']) ){ echo ' ' . $data['delimiter_html'] . ' ' . $data['current_node'] . '<meta itemprop="position" content="' . $position . '" />' . $data['after']; } } else { //Post Category $cat = get_the_category(); if ( !empty($cat) ){ $cat = $cat[0]; echo '<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="' . esc_url(get_term_link($cat->term_id, 'category')) . '" itemprop="item"><span itemprop="name">' . $cat->name . '</span></a><meta itemprop="position" content="' . $position . '" /></li> ' . $data['delimiter_html'] . ' '; $position++; if ( !empty($data['current']) ){ echo $data['current_node'] . '<meta itemprop="position" content="' . $position . '" />' . $data['after']; } } } } elseif ( !is_single() && !is_page() && get_post_type() !== 'post' && !is_404() ){ $post_type = get_post_type_object(get_post_type()); echo $data['before'] . '<span itemprop="name">' . $post_type->labels->name . '</span><meta itemprop="position" content="' . $position . '" />' . $data['after']; } elseif ( is_attachment() ){ //@TODO "Nebula" 0: Check for gallery pages? If so, it should be Home > Parent(s) > Gallery > Attachment if ( !empty($post->post_parent) ){ //@TODO "Nebula" 0: What happens if the page parent is a child of another page? echo '<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="' . get_permalink($post->post_parent) . '" itemprop="item"><span itemprop="name">' . strip_tags(get_the_title($post->post_parent)) . '</span></a><meta itemprop="position" content="' . $position . '" /></li> ' . $data['delimiter_html'] . ' ' . strip_tags(get_the_title()); $position++; } else { echo strip_tags(get_the_title()); } } elseif ( is_page() && !$post->post_parent ){ //Page without ancestors/parents if ( !empty($data['current']) ){ echo $data['current_node'] . '<meta itemprop="position" content="' . $position . '" />' . $data['after']; } } elseif ( is_page() && $post->post_parent ){ //Page with ancestors/parents $parent_id = $post->post_parent; $breadcrumbs = array(); while ( $parent_id ){ $page = get_page($parent_id); $breadcrumbs[] = '<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="' . get_permalink($page->ID) . '" itemprop="item"><span itemprop="name">' . strip_tags(get_the_title($page->ID)) . '</span></a><meta itemprop="position" content="' . $position . '" /></li>'; $position++; $parent_id = $page->post_parent; } $breadcrumbs = array_reverse($breadcrumbs); $breadcrumbs_nodes = count($breadcrumbs); for ( $i = 0; $i < $breadcrumbs_nodes; $i++ ){ echo $breadcrumbs[$i]; if ( $i !== $breadcrumbs_nodes-1 ){ echo ' ' . $data['delimiter_html'] . ' '; } } if ( !empty($data['current']) ){ echo ' ' . $data['delimiter_html'] . ' ' . $data['current_node'] . '<meta itemprop="position" content="' . $position . '" />' . $data['after']; } } elseif ( is_tag() ){ $prefix = ''; if ( $data['prefix'] === 'icon' ){ $prefix = '<i class="fa-solid fa-tag"></i>'; } elseif ( $data['prefix'] === 'text' ){ $prefix = 'Tag: '; } echo apply_filters('nebula_breadcrumbs_tag', $data['before'] . $prefix . '<span itemprop="name">' . single_tag_title('', false) . '</span><meta itemprop="position" content="' . $position . '" />' . $data['after'], $data); //echo $data['before'] . '<a class="current-breadcrumb-link" href="' . get_tag_link($thisTag->term_id) . '">'. $prefix . single_tag_title('', false) . '</a>' . $data['after']; //@todo "Nebula": Need to get $thisTag like $thisCat above } elseif ( is_author() ){ //@TODO "Nebula" 0: Support for multi author? is_multi_author() global $author; $userdata = get_userdata($author); echo apply_filters('nebula_breadcrumbs_author', $data['before'] . '<span itemprop="name">' . $userdata->display_name . '</span><meta itemprop="position" content="' . $position . '" />' . $data['after'], $data); } elseif ( is_404() ){ echo apply_filters('nebula_breadcrumbs_error', $data['before'] . '<span itemprop="name">Error 404</span>' . $data['after'], $data); } if ( get_query_var('paged') ){ echo apply_filters('nebula_breadcrumbs_paged', ' (Page ' . get_query_var('paged') . ')', $data); //nbsp is needed here because something is stripping out the first space } echo '</ol>'; } $this->timer('Breadcrumbs', 'end'); }
Override
To override this PHP function, use this hook in your child theme or plugin ("my_custom" can be changed):
add_filter('pre_nebula_breadcrumbs', 'my_custom_breadcrumbs', 10, 2); //The last integer must be 1 more than the actual parameters function my_custom_breadcrumbs($null, $options){ //$null is required, but can be ignored //Write your own code here return true; //Return true to prevent the original function from running afterwords }
You can completely disable this PHP function with a single line actions:
add_filter('pre_nebula_breadcrumbs', '__return_false');