Kama Breadcrumbs
The plugin creates a chain of links from the home page to the currently viewed page. Such a chain is commonly referred to as “breadcrumbs”.
This is a new version — simpler, more stable, extensible, and clearer code. Modified hooks system. Additional functionality. Past code has been significantly improved.
Output of breadcrumbs in the theme (Usage)
Use the following code in the theme file, where you need to output breadcrumbs.
<?php do_action( 'echo_kama_breadcrumbs' ) ?>
Or you can call with parameters:
<?php $args = [ 'sep' => ' › ', 'on_front_page' => false, 'show_post_title' => false, //'markup' => 'Microdata', // RDFa, Microdata, data-vocabulary.org //'priority_tax' => [ 'category' ], //'number_tax' => [ 'category' => 2 ], //'disable_tax' => [ 'post_tags' ], ]; $l10n = [ 'tag' => 'Tag: <b>%s</b>', ]; do_action( 'echo_kama_breadcrumbs', $args, $l10n ); ?>
When you need to get the HTML breadcrumbs (do not display on screen), use the code:
$breadcrumbs = kama_breadcrumbs( $args, $l10n ); // now output where needed echo $breadcrumbs;
Parameters $args
Breadcrumb output settings are specified as an array in the $args parameter. Possible elements of the array:
- sep(string)
- Separator. You can specify it together with HTML wrapper:
<span> » </span>.
Default: ' » ' - on_front_page(true/false)
- Output breadcrumbs on the homepage.
Default: true - show_post_title(true/false)
- Show the post title at the end (the last element). For posts, pages, attachments.
Default: true - show_term_title(true/false)
- Show the taxonomy element title at the end (the last element). For tags, categories, and other taxonomies.
Default: true - last_sep(true/false)
- show the last separator when the title at the end is not displayed.
Default: true - nofollow(true/false)
- Add
rel=nofollowto links?
Default: false - wrap_class(string)
- CSS class for the main
div.
Default: 'kama_breadcrumbs' - link_class(string)
- CSS class for the breadcrumb item
a.
Default: 'kb_link' - title_class(string)
- CSS class for the title of the item.
Default: 'kb_title' - sep_class(string)
- CSS class for the separator.
Default: 'kb_sep' - priority_tax(array)
Priority taxonomies, needed when a post is in several taxonomies:
array( 'category', 'tax_name' ).
The order matters — the earlier, the more important.In the values you can specify priority elements of taxonomies, then the taxonomy name should be specified in the key.
When a post is in several elements of the same taxonomy simultaneously. For example:
array( 'category' => [ 45, 'term_name', 'терм имя' ], 'tax_name' => [ 1, 2, 'name' ] )
In this code
categoryis the taxonomy name for which priority elements are specified.45- term IDterm_name- label-
терм имя- title.The order
45,term_nameandтерм имяmatters: earlier is more important. All specified terms are more important than unspecified ones.
Default: array()
- disable_tax
- Taxonomies to exclude from display in breadcrumbs:
array( 'post_tag', 'tax_name' )
Default: array() - number_tax
Allows displaying in breadcrumbs for posts several taxonomies.
For example, if you specify
[ 'post' => 2 ], for the post typepostbreadcrumbs will be shown for two taxonomies by default:categoryandpost_tag.You can change the order in the
priority_taxparameter.
Default: array()- markup(string/array)
Microdata. Can be:
Microdata- more about markup here.RDFa- more about markup here.data-vocabulary.org.''- no microdata.
You can specify your own markup array, for example:
'markup' => [ 'wrappatt' => '<div class="kama_breadcrumbs">%s</div>', 'linkpatt' => '<a href="%s">%s</a>', 'titlepatt' => '<span class="kb_title">%s</span>', 'seppatt' => '<span class="kb_sep">%s</span>' ],
Default: 'Microdata'
- JSON_LD(true/false)
- Should JSON-LD microdata be added to the HTML.
Default: true - use_the_title_filter(true/false)
- Should the [the_title] filter be used for post titles.
Default: false
Parameters $l10n
Localization strings are specified in the $l10n parameter as an array. Default values:
// Localization $l10n = array( 'home' => 'Home', 'paged' => 'Page %d', '_404' => 'Error 404', 'search' => 'Search results for - <b>%s</b>', 'author' => 'Author archive: <b>%s</b>', 'year' => 'Archive for <b>%d</b> year', 'month' => 'Archive for: <b>%s</b>', 'day' => 'Archive for <b>%1$s number</b>, %2$s', // Archive for 5th, Wednesday 'attachment' => 'Media: %s', 'tag' => 'Posts by tag: <b>%s</b>', 'tax_tag' => '%1$s from "%2$s" by tag: <b>%3$s</b>', // tax_tag will output: 'post_type from "taxonomy_name" by tag: term_name'. // If separate holders are needed, for example only the term name, write: 'posts by tag: %3$s' );
Strings are translated to English if the site language is English.
Filters (hooks)
All plugin hooks. Below is the code showing how the hook is defined in the plugin:
// Allows disabling breadcrumb output if( apply_filters( 'disable_kama_breadcrumbs', null ) ) return;
// filters localization strings - $l10n is an array $l10n = apply_filters( 'kama_breadcrumbs_l10n', $l10n );
// filters parameters - $args is an array $args = apply_filters( 'kama_breadcrumbs_args', $args );
// output: all kinds of posts with terms, or terms $term = apply_filters( 'kama_breadcrumbs_term', $term );
// ability to change breadcrumb elements /** * Allows change breadcrumbs elements. * * @param Kama_Breadcrumbs_Elem[] $elms Multidimensional associative array of breadcrumbs elements. * @param Kama_Breadcrumbs $this Object of current class. * @param WP_Post_Type|null $ptype Post Type object. Null when post type for the current query is not detected. */ $elms = apply_filters( 'kama_breadcrumbs_filter_elements', $elms, $this, $this->ptype );
// ability to change breadcrumb elements, // after all elements have been gathered into a flat array /** * Allows change breadcrumbs elements after it's all elements where * collected in the flat array. * * @param Kama_Breadcrumbs_Elem[] $elms Associative array of elements. * @param Kama_Breadcrumbs $this Object of current class. * @param WP_Post_Type|null $ptype Post Type object. Null when post type for the current query is not detected. */ $flat_elms = apply_filters( 'kama_breadcrumbs_filter_flat_elements', $flat_elms, $this, $ptype );
// filters the ready HTML code of breadcrumbs return apply_filters( 'kama_breadcrumbs', sprintf( $arg->wrappatt, $out ), $arg->sep, $loc, $arg );
Usage examples for hooks
Changing default parameters
// set default parameters
add_filter( 'kama_breadcrumbs_args', 'my_kama_breadcrumbs_args' );
function my_kama_breadcrumbs_args( $args ){
$my_args = [
'sep' => ' › ', // ▸
'on_front_page' => 1,
'show_post_title' => 0,
//'show_term_title' => 0,
//'last_sep' => 0,
'markup' =>'RDFa',
// or your own markup
'markup' => [
'wrappatt' => '<div class="kama_breadcrumbs">%s</div>',
'linkpatt' => '<li><a href="%s">%s</a></li>',
'titlepatt' => '<li class="active">%s</li>',
'seppatt' => '<span class="kb_sep">%s</span>',
],
'priority_tax' => [ 'category', 'tplcat', 'wpfunccat' ],
];
return $my_args + $args;
}
Localization (translation strings)
// modify translation strings
add_filter( 'kama_breadcrumbs_l10n', 'my_kama_breadcrumbs_l10n' );
function my_kama_breadcrumbs_l10n( $l10n ){
$my_l10n = [
'home' => '<i style="display:none;">Home</i><span class="dashicons dashicons-admin-home"></span>',
'tax_tag' => 'By tag: <b>%3$s</b>',
];
return $my_l10n + $l10n;
}
Change/Add breadcrumb elements
To change existing URLs in breadcrumbs or add your own breadcrumbs, use the filter kama_breadcrumbs_filter_elements.
The function attached to this filter receives the array and must return the modified array. This array is exactly the breadcrumbs, but in the form of a multidimensional array, which will later be converted to the HTML code of breadcrumbs.
To modify or create breadcrumb elements two methods are used (they automatically create the microdata specified in the markup parameter):
// for any breadcrumb element (except the last) $class->makelink( $url, $title ) // for the last breadcrumb element (the link will be output only if needed) $class->maketitle( $url, $title )
The code must be inserted into the theme file's functions.php or somewhere else, the main thing is before the breadcrumbs are output.
#1 Example of changing breadcrumb elements
To make everything clear I’ll go step by step.
All changes to breadcrumbs are done through the filter kama_breadcrumbs_filter_elements. First, let's see what’s in the breadcrumbs to understand which keys the array has:
add_filter( 'kama_breadcrumbs_filter_elements', 'kama_breadcrumbs_filter_elms', 11, 3 );
function kama_breadcrumbs_filter_elms( $elms, $class, $ptype ){
die( print_r( $elms ) );
}
As a result you’ll see such an array (if we are on a post page):
Array ( [home] => Array ( [0] => Kama_Breadcrumbs_Elem Object ( ... ) ) [home_after] => Array( ) [single] => Array ( [category__tax_crumbs] => Array ( [0] => Kama_Breadcrumbs_Elem Object( ... ) [1] => Kama_Breadcrumbs_Elem Object( ... ) ) ) )
As you can see there are 3 breadcrumbs here: home > category > category (refer to the array keys — they do not change and depend on the type of data to which a particular breadcrumb belongs).
Now, for example, we need to change the home page link, so we modify the breadcrumb located under the home key:
add_filter( 'kama_breadcrumbs_filter_elements', function( $elms, $class, $ptype ){
$elms['home'] = $class->makelink( 'https://site.com/path', 'Title' );
return $elms; // don’t forget to return
}, 11, 3 );
Or you can add another breadcrumb after the home link by pushing another element into the array with the home key:
add_filter( 'kama_breadcrumbs_filter_elements', function( $elms, $class, $ptype ){
$elms['home'][] = $class->makelink( 'https://site.com/path', 'Title' );
return $elms; // don’t forget to return
}, 11, 3 );
Using this approach you can delete/change/add breadcrumbs as you like.
Note that the array understands any level of nesting. For example, you can write it like this and everything will work:
add_filter( 'kama_breadcrumbs_filter_elements', function( $elms, $class, $ptype ){
$elms['home'][] = [
'foo' => [
$class->makelink( 'https://site.com/path', 'Title' )
]
];
return $elms; // don’t forget to return
}, 11, 3 );
#2 Add breadcrumb elements after the home link
// add your own links to breadcrumbs
add_filter( 'kama_breadcrumbs_filter_elements', 'breadcrumbs_add_elements', 10, 3 );
function breadcrumbs_add_elements( $elms, $class, $ptype ){
global $post;
// check what elements exist in the array and add where and what you need
// print_r( $elms );
// the post is in the category mycat
if( is_single() && has_category( 'mycat', $post ) ){
// add 2 links (2 elements) after the home
$elms['home'][] = [
$class->makelink( '/inventory', 'Inventory' ),
$class->makelink( '/other', 'Other' )
];
}
return $elms;
}
#3 Example for WooCommerce
add_filter( 'kama_breadcrumbs_filter_elements', 'kama_breadcrumbs_add_elements', 10, 3 );
function kama_breadcrumbs_add_elements( $elms, $class, $ptype ){
if ( is_woocommerce() ) {
$page = get_post( wc_get_page_id( 'shop' ) );
if ( is_shop() && ! is_paged() ) {
$elms['home_after'] = $class->maketitle( get_the_permalink( $page ), get_the_title( $page ) );
}
else {
$elms['home_after'] = $class->makelink( get_permalink( $page ), get_the_title( $page ) );
}
}
return $elms;
}
#4 Ways to add a “breadcrumb” after the home
add_filter( 'kama_breadcrumbs_filter_elements', 'kama_breadcrumbs_add_elements', 10, 3 );
function kama_breadcrumbs_add_elements( $elms, $class, $ptype ){
// you can do this:
$elms['home_after'][] = $class->makelink( 'http://example.com/functions', 'Functions' );
// or delete the existing elements and add your own:
$elms['home_after'] = $class->makelink( 'http://example.com/functions', 'Functions' );
// or add several links at once:
$elms['home_after'][] = [
$class->makelink('http://example.com/functions', 'Functions' ),
$class->makelink('http://example.com/hooks', 'Hooks' ),
];
// or replace with several of your own links (remove the current home_after value):
$elms['home_after'] = [
$class->makelink('http://example.com/functions', 'Functions' ),
$class->makelink('http://example.com/hooks', 'Hooks' ),
];
return $elms;
}
The $elms array
What the $elms array looks like before being passed to the hook (elements will differ on different pages of the site):
Array( [home] => <span property="itemListElement" typeof="ListItem"> <a href="http://example.com" property="item" typeof="WebPage"><span property="name"><i style="display:none;">Home</i><span class="dashicons dashicons-admin-home"></span></span></a> <meta property="position" content="ORDERNUM" /> </span> [home_after] => Array( [0] => <span property="itemListElement" typeof="ListItem"> <a href="/functions" property="item" typeof="WebPage"><span property="name">Functions</span></a> <meta property="position" content="ORDERNUM" /> </span> [1] => <span property="itemListElement" typeof="ListItem"> <a href="/functions/template_tags" property="item" typeof="WebPage"><span property="name">Template tags</span></a> <meta property="position" content="ORDERNUM" /> </span> ) [single] => Array( [wpfunccat__tax_crumbs] => Array( [0] => <span property="itemListElement" typeof="ListItem"> <a href="http://example.com/function-cat/miscellaneous" property="item" typeof="WebPage"><span property="name">Miscellaneous functions</span></a> <meta property="position" content="ORDERNUM" /> </span> [1] => <span property="itemListElement" typeof="ListItem"> <a href="http://example.com/function-cat/zaschita-bloga" property="item" typeof="WebPage"><span property="name">Blog protection</span></a> <meta property="position" content="ORDERNUM" /> </span> ) [title] => <span class="kb_title" property="itemListElement" typeof="ListItem"> <span property="name">form_option</span> <meta property="position" content="ORDERNUM"> </span> ) )
You can add your own elements to this array. In the value there can be a string or a nested array. As a result, all values of this multidimensional array will be collected and output in the breadcrumbs in order.
Names of the $elms array keys. For example, home_after is needed to make it easier to “slot” your own link in the right place, but they do not affect the code operation. That is, when adding your own elements, the array key can be any or you can omit it altogether.
Getting the breadcrumbs array (not the HTML code)
Since version 4.22 there are two methods to obtain the data array of breadcrumbs without outputting HTML to the screen.
$args = []; $breadcrumbs = new Kama_Breadcrumbs( $args ); print_r( $breadcrumbs->get_crumbs_flat_elements() ); // or print_r( $breadcrumbs->get_crumbs_elements() );
Removing elements from breadcrumbs
When you need to remove existing elements, just like when adding, use the filter kama_breadcrumbs_filter_elements.
So, to, for example, remove the Home link, you need to remove the array element, more precisely clear it:
// modify breadcrumbs
add_filter( 'kama_breadcrumbs_filter_elements', 'breadcrumbs_change_elements', 10, 3 );
function breadcrumbs_change_elements( $elms, $class, $ptype ){
global $post;
// see what elements exist in the array and add where and what you need
// print_r( $elms );
// remove the Home link (clear the element at home)
$elms['home'] = [];
return $elms;
}
Disable breadcrumbs (by condition)
Suppose we need to disable breadcrumb output on the /profile page. This can be done via the filter disable_kama_breadcrumbs:
add_filter( 'disable_kama_breadcrumbs', function(){
return is_page('profile');
} );
Or if your breadcrumbs are output via the hook echo_kama_breadcrumbs, you can simply remove all functions attached to it:
add_action( 'wp', function(){
if( is_page('profile') ){
remove_all_filters( 'echo_kama_breadcrumbs' );
}
} );
Changing classes for BEM markup
## default parameters — kama_breadcrumbs
add_filter( 'kama_breadcrumbs_args', function( $args )
{
$base = isset($args['bem']['base']) ? $args['bem']['base'] : 'breadcrumbs';
$mods = isset($args['bem']['mods']) ? $args['bem']['mods'] : [];
$inner = $base . '__inner';
$item = $base . '__item';
$title = $base . '__title';
$link = $base . '__link';
$sep = $base . '__sep';
$base_mod = isset($mods['base']) ? ' ' . $base . '--' . $mods['base'] : '';
$inner_mod = isset($mods['inner']) ? ' ' . $inner . '--' . $mods['inner'] : '';
$item_mod = isset($mods['item']) ? ' ' . $item . '--' . $mods['item'] : '';
$title_mod = isset($mods['title']) ? ' ' . $title . '--' . $mods['title'] : '';
$link_mod = isset($mods['link']) ? ' ' . $link . '--' . $mods['link'] : '';
$sep_mod = isset($mods['sep']) ? ' ' . $sep . '--' . $mods['sep'] : '';
return array_merge( $args, [
'sep' => ' — ',
'sep_class' => $sep . $sep_mod,
// custom markup
'markup' =>
[
'wrappatt' => '
<div class="' . $base . $base_mod . '" itemscope itemtype="https://schema.org/BreadcrumbList">
<div class="' . $inner . $inner_mod . '">%s</div>
</div>',
'linkpatt' => '
<span class="' . $item . $item_mod . '" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a href="%s" class="' . $link . $link_mod . '">%s</a>
<meta itemprop="item" content="PERMALINK" />
<meta itemprop="name" content="NAME" />
<meta itemprop="position" content="ORDERNUM" />
</span>',
'titlepatt' => '
<span class="' . $title . $title_mod . '" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
%s
<meta itemprop="item" content="PERMALINK" />
<meta itemprop="name" content="NAME" />
<meta itemprop="position" content="ORDERNUM" />
</span>
',
],
] );
} );
## template usage example:
$bc_args = [
'bem' => [
'mods' => [
'inner' => 'grey_class',
'link' => 'red_color',
],
]
];
echo kama_breadcrumbs( $bc_args );
/**
* Will output:
* - wrapper has class="breadcrumbs__inner breadcrumbs__inner--grey_class"
* - links have class="breadcrumbs__link breadcrumbs__link--red_color"
*/