How can i create breadcrumb home->page->post
name when we click on main menu any page, open the list of post that time breadcrumb create home ->page
name its ok but now when we click on any post that time breadcrumb create home->post
category name->post
name is is that when we click on post category name on breadcrumb layout shown different we want to its goes on page link, not category link. so we need to when we open any post we need to create the breadcrumb like this home->page name->post
name so when we click on page name open the post list page, not category page.

- 4,930
- 4
- 27
- 45

- 141
- 1
- 2
- 9
-
Do you mean just to show a row with breadcrumbs under the header or just have a link structure for url? – lisarko8077 Jun 17 '18 at 05:36
3 Answers
WordPress doesn't provide builtin breadcrumbs functionality. Thus you'll have to either use a plugin or else code it yourself (or copy from the reference below).
As a matter of fact, the plugin or custom code, if providing similar functionality, make not much of a difference. Thus use the one which is more convenient for you.
If you would like to add a custom code, here are few resources which I could look up on search:
https://www.techpulsetoday.com/wordpress-breadcrumbs-without-plugin/
https://www.thewebtaylor.com/articles/wordpress-creating-breadcrumbs-without-a-plugin
https://www.codexworld.com/wordpress-how-to-display-breadcrumb-without-plugin/
https://gist.github.com/tinotriste/5387124
You can look into them and modify them as you wish!
I hope it helps!

- 3,715
- 2
- 24
- 37
-
31st one works without a hitch. Bonus - it's nice and compact, doesn't do that irritating spaced out code thing. – Vörös Imi Jun 27 '19 at 14:46
-
4
I can't understand how an answer with only pasted links can get to that many upvote. The regular WordPress breadcrumb approach is painfully unoptimized, most of the one out there do not suit custom themes. I decided to built a URL based breadcrumb which is, from my point of view, far more efficient and adaptable. I wanted something generic, SEO friendly, without any default styling. It needed also to properly handle posts and pages title.
Version | |
---|---|
Requires at least WordPress: | 5.0.0 |
Requires at least PHP: | 7.0.0 |
Tested up to WordPress: | 6.0.2 |
The latest version is available on my GitHub as an unofficial WordPress plugin.
<?php
/**
* Checks if a string ends with a given substring.
* Backward compatibility for PHP < 8.0.0.
*
* @since 1.2.0
* @param String $haystack The string to search in.
* @param String $needle The substring to search for in the haystack.
* @return Boolean
*/
if ( ! function_exists( 'backward_compatibility_str_ends_with' ) ) {
function backward_compatibility_str_ends_with( $haystack, $needle ) {
$length = strlen( $needle );
if ( ! $length ) {
return true;
};
return substr( $haystack, -$length ) === $needle;
};
};
/**
* Determine if a string contains a given substring.
* Backward compatibility for PHP < 8.0.0.
*
* @since 1.2.0
* @param String $haystack The string to search in.
* @param String $needle The substring to search for in the haystack.
* @return Boolean
*/
if ( ! function_exists( 'backward_compatibility_str_contains' ) ) {
function backward_compatibility_str_contains( $haystack, $needle ) {
if ( strpos( $haystack, $needle ) !== false ) {
return true;
};
};
};
/**
* Retrieve the crumbs.
*
* @since 1.0.0
* @return Array Crumbs array.
*/
if ( ! function_exists( 'get_the_crumbs' ) ) {
function get_the_crumbs() {
/**
* $_SERVER["REQUEST_SCHEME"] seems to be UNRELIABLE.
*
* Article "Is $_SERVER['REQUEST_SCHEME'] reliable?".
* @see https://stackoverflow.com/a/18008178/3645650
*
* $_SERVER['REQUEST_SCHEME'] is a native variable of Apache web server since its version 2.4.
* Naturally, if a variable is not set by the server, PHP will not include it in its global array $_SERVER.
*
* An alternative to $_SERVER['REQUEST_SCHEME'] is $_SERVER['HTTPS'] which set to a non-empty value if the script was queried through the HTTPS protocol.
*
* Article "How to find out if you're using HTTPS without $_SERVER['HTTPS']".
* @see https://stackoverflow.com/a/16076965/3645650
*/
if ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] == 'on' ) {
$server_scheme = 'https';
} elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || ! empty( $_SERVER['HTTP_X_FORWARDED_SSL'] ) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on' ) {
$server_scheme = 'https';
} else {
$server_scheme = 'http';
};
/**
* $_SERVER["REQUEST_URI"] seems to be RELIABLE.
* $_SERVER['REQUEST_URI'] will not be empty in WordPress, because it is filled in wp_fix_server_vars() (file wp-includes/load.php).
*
* Article "Is it safe to use $_SERVER['REQUEST_URI']?".
* @see https://wordpress.stackexchange.com/a/110541/190376
*/
$server_uri = $_SERVER['REQUEST_URI'];
/**
* $_SERVER["HTTP_HOST"] seems to be RELIABLE.
*
* Article "How reliable is HTTP_HOST?".
* @see https://stackoverflow.com/a/4096246/3645650
*/
$server_host = $_SERVER["HTTP_HOST"];
if ( backward_compatibility_str_contains( $server_uri, '?' ) ) {
$server_uri = substr( $server_uri, 0, strpos( $server_uri, '?' ) );
};
if ( backward_compatibility_str_ends_with( $server_uri, '/' ) ) {
$server_uri = explode( '/', substr( $server_uri, 1, -1 ) );
} else {
$server_uri = explode( '/', substr( $server_uri, 1 ) );
};
$crumbs = array();
foreach ( $server_uri as $crumb ) {
$slug = esc_html( urldecode( $crumb ) );
$url = esc_url( $server_scheme . '://' . $server_host . '/' . substr( implode( '/', $server_uri ), 0, strpos( implode( '/', $server_uri ), $crumb ) ) . $crumb. '/' );
array_push( $crumbs,
array(
'slug' => $slug,
'url' => $url,
)
);
};
/**
* WordPress, by default, doesn't generate a taxonomy index, meaning https://.../taxonomy will redirect to a 404.
* Any request needs to be made against a term. eg: https://.../taxonomy/term will redirect to taxonomy.php.
* Therefore we need to remove the taxonomy slug from the crumbs array to avoid displaying a link to a 404.
*
* We round up all taxonomies through get_taxonomies().
* @see https://developer.wordpress.org/reference/functions/get_taxonomies/
*
* Through array_filter we filter-out any matching crumbs.
* @see https://www.php.net/manual/en/function.array-filter.php
*/
$banned_slugs = array();
$taxonomies = get_taxonomies(
array(
'public' => true,
),
'objects'
);
foreach ( $taxonomies as $taxonomy ) {
array_push( $banned_slugs, $taxonomy->name );
if ( isset( $taxonomy->rewrite['slug'] ) ) {
array_push( $banned_slugs, $taxonomy->rewrite['slug'] );
};
};
$banned_crumbs = array();
foreach ( $banned_slugs as $banned_slug ) {
$slug = esc_html( $banned_slug );
$url = esc_url( $server_scheme . '://' . $server_host . '/' . substr( implode( '/', $server_uri ), 0, strpos( implode( '/', $server_uri ), $banned_slug ) ) . $banned_slug. '/' );
array_push( $banned_crumbs,
array(
'slug' => $slug,
'url' => $url,
)
);
};
$crumbs = array_filter( $crumbs, function( $crumb ) use ( $banned_slugs ) {
if ( ! in_array( $crumb['slug'], $banned_slugs ) && ! in_array( $crumb['url'], $banned_slugs ) ) {
return ! in_array( $crumb['slug'], $banned_slugs );
};
} );
return $crumbs;
};
};
/**
* Display the bread, a formatted crumbs list.
*
* @since 1.0.0
* @param Array $ingredients The bread arguments.
* @param Array $ingredients['crumbs'] The crumbs array. Default to get_the_crumbs().
* @param Array $ingredients['root'] Root crumb. Default to null.
* @param String $ingredients['root']['slug'] Root crumb slug.
* @param String $ingredients['root']['url'] Root crumb url.
* @param String $ingredients['separator'] The crumb's separator.
* @param Integer $ingredients['offset'] Crumbs offset. Accept positive/negative Integer. Default to "0". Refer to array_slice, https://www.php.net/manual/en/function.array-slice.php.
* @param Integer $ingredients['length'] Crumbs length. Accept positive/negative Integer. Default to "null". Refer to array_slice, https://www.php.net/manual/en/function.array-slice.php.
* @return Array The formatted crumbs list.
*/
if ( ! function_exists( 'the_bread' ) ) {
function the_bread( $ingredients = array() ) {
if ( empty( $ingredients['crumbs'] ) ) {
$crumbs = get_the_crumbs();
} else {
$crumbs = $ingredients['crumbs'];
};
if ( empty( $ingredients['root'] ) ) {
$root = null;
} else {
$root = $ingredients['root'];
};
if ( empty( $ingredients['offset'] ) ) {
$offset = 0;
} else {
$offset = $ingredients['offset'];
};
if ( empty( $ingredients['length'] ) ) {
$length = null;
} else {
$length = $ingredients['length'];
};
/**
* Handling the root crumb case.
* Prepend one or more elements to the beginning of an array.
* @see https://www.php.net/manual/en/function.array-unshift.php
*/
if ( ! empty( $root ) ) {
array_unshift( $crumbs, $ingredients['root'] );
};
/**
* Handling the length case.
* Extract a slice of the array.
* @see https://www.php.net/manual/en/function.array-slice.php
*/
$crumbs = array_slice( $crumbs, $offset, $length );
if ( ! empty( $crumbs ) ) {
echo '<ol class=" bread" itemscope itemtype="https://schema.org/BreadcrumbList">';
$i = 0;
foreach ( $crumbs as $crumb ) {
$i++;
/**
* Unparsing the slug.
*/
if ( url_to_postid( $crumb['url'] ) ) {
$title = get_the_title( url_to_postid( $crumb['url'] ) );
} elseif ( get_page_by_path( $crumb['slug'] ) ) {
$title = get_the_title( get_page_by_path( $crumb['slug'] ) );
} else {
$title = ucfirst( str_replace( '-', ' ', $crumb['slug'] ) );
};
echo '<li class="crumb" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a itemprop="item" href="' . $crumb['url'] . '">
<span itemprop="name">' . $title . '</span>
</a>
<meta itemprop="position" content="' . $i . '">
</li>';
if ( $i !== sizeof( $crumbs ) && ! empty( $ingredients['separator'] ) ) {
echo $ingredients['separator'];
};
};
echo '</ol>';
};
};
};
Displaying the bread, a formatted crumbs list.
<?php
the_bread( $ingredients = array() );
Parameters
Parameter | Description |
---|---|
$ingredients |
(Optional) Array The bread arguments. |
$ingredients['crumbs'] |
Array The crumbs array. Default to get_the_crumbs() . |
$ingredients['root'] |
Array Root crumb. Default to null . |
$ingredients['root']['slug'] |
(Required if $ingredients['root'] ). Root crumb slug. |
$ingredients['root']['url'] |
(Required if $ingredients['root'] ). Root crumb url. |
$ingredients['separator'] |
The crumb's separator. |
$ingredients['offset'] |
Crumbs offset. Accept positive/negative Integer . Default to 0 . Refer to array_slice. |
$ingredients['length'] |
Crumbs length. Accept positive/negative Integer . Default to null . Refer to array_slice. |
Example: The bread with a custom separator
<?php
$ingredients = array(
'separator' => '→',
);
the_bread( $ingredients );
Example: Displaying the last 3 crumbs
<?php
$ingredients = array(
'offset' => -3,
'length' => 3,
);
the_bread( $ingredients );
Example: The bread with a root crumb
<?php
$ingredients = array(
'root' => array(
'slug' => 'home',
'url' => get_home_url(),
),
);
the_bread( $ingredients );
Example: Intercepting the crumbs array
<?php
//Intercept the crumbs array...
$crumbs = get_the_crumbs();
//... Do something with it:
//In our case we're appending a new crumb to the crumbs array.
array_push( $crumbs, array(
'slug' => 'search',
'url' => 'https://.../search/',
) );
$ingredients = array(
'crumbs' => $crumbs,
);
the_bread( $ingredients );
HTML5 structure output
<ol class=" bread" itemscope="" itemtype="https://schema.org/BreadcrumbList">
<li class="crumb" itemprop="itemListElement" itemscope="" itemtype="https://schema.org/ListItem">
<a itemprop="item" href="http://example.com/where/">
<span itemprop="name">Where</span>
</a>
<meta itemprop="position" content="1">
</li>
>
<li class="crumb" itemprop="itemListElement" itemscope="" itemtype="https://schema.org/ListItem">
<a itemprop="item" href="http://example.com/where/is/">
<span itemprop="name">Is</span>
</a>
<meta itemprop="position" content="2">
</li>
>
<li class="crumb" itemprop="itemListElement" itemscope="" itemtype="https://schema.org/ListItem">
<a itemprop="item" href="http://example.com/where/is/my/">
<span itemprop="name">My</span>
</a>
<meta itemprop="position" content="3">
</li>
>
<li class="crumb" itemprop="itemListElement" itemscope="" itemtype="https://schema.org/ListItem">
<a itemprop="item" href="http://example.com/where/is/my/bread/">
<span itemprop="name">Bread</span>
</a>
<meta itemprop="position" content="4">
</li>
</ol>
Minimal css boilerplate (Optional)
.,
.bread {
list-style-type: none;
margin:0;
padding:0;
}
. li,
.bread li {
display:inline-block;
}
. li.crumb:last-child a,
.bread li.crumb:last-child a {
text-decoration: none;
pointer-events: none;
color: inherit;
}
Retrieving the crumbs
Even tho we recommend you to use the_bread()
function to display and build your own breadcrumb, you can use get_the_crumbs()
to retrieve the crumbs object.
Example: Outputting the crumbs object
<?php
var_dump( get_the_crumbs() );

- 4,930
- 4
- 27
- 45
-
1This is really neat and light-weight. The only problem I've seen thus farr, is that there isn't any handling of static permalink parts, such as `/category/` which doesn't have any content, nor a page ID. I could probably customize it to not print those out though. – InanisAtheos Jun 12 '21 at 13:56
-
I didn't notice the Github link, nor that there is a later version. I'll have a look. And yea I could create that page I guess. However I solved it with an array of "banned" links to check against before printing the results. – InanisAtheos Jun 12 '21 at 20:10
-
1@Athoxx [Version `1.0.3`](https://github.com/amarinediary/Where-Is-My-Bread) automatically filter out posts types and taxonomies root crumbs. – amarinediary Nov 30 '21 at 21:05
-
-
-
You would have to be more precise on that, you can [open a new issue](https://github.com/amarinediary/WordPress-simple-URL-based-breadcrumb/issues/new) on github explaining your idea/problem and I will do my best to answer it. – amarinediary Sep 15 '22 at 10:39
A minimalistic breadcrumbs generator in a few lines as a filter:
add_filter( 'my_get_breadcrumbs', [ $this, 'the_breadcrumbs' ], 10, 1 );
/**
* Returns a list of all the breadcrumbs for the current page.
* usage: apply_filters( 'my_get_breadcrumbs', false )
*
* @param $max_depth int
*
* @return string
*/
function the_breadcrumbs() {
$crumbs = '';
$current_page_id = get_the_ID();
$parent = wp_get_post_parent_id( $current_page_id );
$index = 0;
while ( $parent ) {
$index ++;
$crumbs = '<li><a href="' . get_permalink( $parent ) . '">' . get_the_title( $parent ) . '</a></li>' . $crumbs;
$parent = wp_get_post_parent_id( $parent );
if ( $index > 10 ) {
break;
}
}
return $crumbs . '<li><a>' . get_the_title( $current_page_id ) . '</a></li>';
}

- 684
- 1
- 7
- 28