Breadcrumbs: List breadcrumbs created from path alias
Last modified: November 7, 2006 - 22:43
There are just times when it's easier for me to structure the site by path alias, and I'd like my breadcrumbs to reflect that. Here's a script that will read what your path alias is, and create breadcrumbs reflecting that. It will check to see if the path is related to a taxonomy or node, and return the proper title. If there isn't a path or node (such as pathauto created indexes), then it will just list the word or words as the title.
Place this in your template.php
<?php
function url_breadcrumbs() {
function get_crumb($lvl){
$uri_request_id = $_SERVER['REQUEST_URI'];
$urlexplode = explode("?", $uri_request_id);
$url = explode("/",$urlexplode[0]);
if($url[$lvl]){
if($lvl > 1) {
$var = array_keys($url);
foreach($var as $vars){
if($vars == 1){
$urlpathpeice .= $url[$vars];
}
if($vars <= $lvl && $vars > 1){
$urlpathpeice .= '/'.$url[$vars];
}
}
$urlpathalias = $urlpathpeice;
} elseif ($lvl == 1) {
$urlpathalias = $url[$lvl];
}
$urlsystem = drupal_lookup_path('source', $urlpathalias);
$urlsystemexplode = explode("/", $urlsystem);
$urltype = $urlsystemexplode[0];
if($urltype == "taxonomy"){
$term = taxonomy_get_term($urlsystemexplode[2]);
if($url[$lvl+1]){
return ' >> <a href="/'.$urlpathalias.'" title="'.$term->name.'">'.$term->name.'</a>';
} else {
return ' >> '.$term->name.'';
}
} elseif($urltype == "node"){
$node = node_load($urlsystemexplode[1]);
if($url[$lvl+1]){
return ' >> <a href="/'.$urlpathalias.'" title="'.$nodename.'">'.$node->title.'</a>';
} else {
return ' >> '.$node->title;
}
} else {
$urltitleexplode = explode("-", $url[$lvl]);
$words = array_keys($urltitleexplode);
foreach($words as $word){
$urltitle .= ''.ucwords($urltitleexplode[$word]).' ';
}
if($url[$lvl+1]) {
return ' >> <a href="/'.$urlpathalias.'" title="'.$urltitle.'">'.$urltitle.'</a>';
} else {
return ' >> '.$urltitle.'';
}
}
}
}
function get_crumb_all() {
$uri_request_id = $_SERVER['REQUEST_URI'];
$urlexplode = explode("?", $uri_request_id);
$url = explode("/",$urlexplode[0]);
$numbs = array_keys($url);
foreach($numbs as $numb) {
$crumbs .= get_crumb($numb);
}
return $crumbs;
}
$output .= '<div class="breadcrumb">';
$output .= '<a href="/" title="Home">Home</a>';
$output .= get_crumb_all();
$output .= '</div>';
return $output;
}
?>then, wherever you want the breadcrumbs, such as page.tpl.php
<?php
print url_breadcrumbs();
?>This hasn't been tested extensively. It works for the one site I needed it for.
I'm not really a coder, so please excuse any strangeness, this is about all I know.

Works in 5.x with small adjustment
This worked for me, but you have to have 3 different functions, not two functions wrapped in another...
get crumb { [as above] }
get_all_crumb{ [as above] }
url_breadcrumbs{
$output .= '';
$output .= 'Home';
$output .= get_crumb_all();
$output .= '';
return $output;
}
Note that this seems to disable the normal print $breadcrumb for some reason (if anyone knows why or a work-around that would be great...)
Thanks!
trimmed white space in <a>
majnoona's mod worked for me in 5.2
I added a trim($urltitle) to take out the trailing whitespace.
Here is the full code to add to your template.php:
<?php
function get_crumb($lvl) {
$uri_request_id = $_SERVER['REQUEST_URI'];
$urlexplode = explode("?", $uri_request_id);
$url = explode("/",$urlexplode[0]);
if($url[$lvl]){
if($lvl > 1) {
$var = array_keys($url);
foreach($var as $vars){
if($vars == 1){
$urlpathpeice .= $url[$vars];
}
if($vars <= $lvl && $vars > 1){
$urlpathpeice .= '/'.$url[$vars];
}
}
$urlpathalias = $urlpathpeice;
} elseif ($lvl == 1) {
$urlpathalias = $url[$lvl];
}
$urlsystem = drupal_lookup_path('source', $urlpathalias);
$urlsystemexplode = explode("/", $urlsystem);
$urltype = $urlsystemexplode[0];
if($urltype == "taxonomy"){
$term = taxonomy_get_term($urlsystemexplode[2]);
if($url[$lvl+1]){
return ' » <a href="/'.$urlpathalias.'" title="'.$term->name.'">'.$term->name.'</a>';
} else {
return ' » '.$term->name.'';
}
} elseif($urltype == "node"){
$node = node_load($urlsystemexplode[1]);
if($url[$lvl+1]){
return ' » <a href="/'.$urlpathalias.'" title="'.$nodename.'">'.$node->title.'</a>';
} else {
return ' » '.$node->title;
}
} else {
$urltitleexplode = explode("-", $url[$lvl]);
$words = array_keys($urltitleexplode);
foreach($words as $word){
$urltitle .= ''.ucwords($urltitleexplode[$word]).' ';
}
// Removes trailing whitespace
$urltitle = trim($urltitle);
if($url[$lvl+1]) {
return ' » <a href="/'.$urlpathalias.'" title="'.$urltitle.'">'.$urltitle.'</a>';
} else {
return ' » '.$urltitle.'';
}
}
}
}
function get_crumb_all() {
$uri_request_id = $_SERVER['REQUEST_URI'];
$urlexplode = explode("?", $uri_request_id);
$url = explode("/",$urlexplode[0]);
$numbs = array_keys($url);
foreach($numbs as $numb) {
$crumbs .= get_crumb($numb);
}
return $crumbs;
}
function url_breadcrumbs() {
$output .= '';
$output .= 'Home';
$output .= get_crumb_all();
$output .= '';
return $output;
}
?>
this code is useless if you
this code is useless if you have an internationalized drupal and/or your drual is running in a subdirectory. in these 2 cases the breadcrumb will be something like:
"Home > drupalsubfolder > [dir]"
or
"Home > es > [dir]"
front page without "Home"
u can hide the "Home" from the frontpage, just upgrade this section in template.php:
function get_crumb_all() {$uri_request_id = $_SERVER['REQUEST_URI'];
$urlexplode = explode("?", $uri_request_id);
$url = explode("/",$urlexplode[0]);
$numbs = array_keys($url);
foreach($numbs as $numb) {
$crumbs .= get_crumb($numb);
}
if ($crumbs){
echo '<a href="/" title="Home">Home</a>';
}
return $crumbs;
}
http://eaposztrof.com/drupal | save the planet, kill yourself!
thank you, but the problem
thank you, but the problem is with the i18n suffix (e.g. "en", "fr", etc.) and the subfolder that are displayed in the URL and hence in the breadcrumbs. i'm pretty sure this can be solved through some php function, but i don't know how. thank you for your help.
version for Drupal 6.1 dealing with subfolders
modified the code ... i'm working in Drupal 6.1 and the way i got around the subfolders problem was using the base_path() function, which returns the path of the Drupal install (which would be the path to the subfolder). i don't know what base_path() returns in an international install, so if somebody can post about that, it'd be great.
i added the argument $breadcrumb (just pass in the $breadcrumb var when you call url_breadcrumb in page.tpl.php). i commented in the code about how to remove "Home" and the current page's title, if that's what you want. let me know if this works ok or could be better :) hope it helps.
<?php
function url_breadcrumb($breadcrumb) {
$url = path_alias_array();
// On admin pages, use the default breadcrumb. But I prefer having the
// title of the current page display as well. So I remove the '</div>'
// tag from the original breadcrumb with substr() and add in the title with
// drupal_get_title().
if ($url[0] == 'admin')
return substr($breadcrumb, 0, -6) . ' » <strong>' . drupal_get_title() . '</strong></div>';
$output .= '<div class="breadcrumb">';
// Remove this line if you don't like the Home link. You'll need to adjust
// the code below too, to not display ">>" (») at the start of the
// breadcrumb
$output .= '<a href="' . base_path() . '" title="Home">Home</a>';
$output .= get_crumb_all();
$output .= '</div>';
return $output;
}
// Extract the URL path alias from the URI
function path_alias_array() {
$uri_request_id = $_SERVER['REQUEST_URI'];
$urlexplode = explode("?", $uri_request_id);
if (base_path() != '/') {
$urlfinal = explode(base_path(), $urlexplode[0]);
$url = explode("/", $urlfinal[1]);
}
else {
$url = explode("/", $urlexplode[0]);
}
return $url;
}
// Get full breadcrumb
function get_crumb_all() {
$url = path_alias_array();
// Construct each piece of the breadcrumb
$numbs = array_keys($url);
foreach ($numbs as $numb) {
$crumbs .= get_crumb($numb);
}
return $crumbs;
}
// Get breadcrumb piece
function get_crumb($lvl){
$url = path_alias_array();
// Reconstruct path alias as string
for ($i = 0; $i < $lvl+1; $i++) {
$urlpathalias .= $url[$i];
if ($i != $lvl)
$urlpathalias .= '/';
}
$urlpathalias = str_replace('%20', ' ', $urlpathalias);
// If Drupal install is not in a subdir, we need to remove extra '/'
if ($urlpathalias[0] == '/')
$urlpathalias = substr($urlpathalias, 1);
// If at Home, return now so we don't append the '>>'
if ($urlpathalias == '')
return;
// It is assumed that all paths are URL path aliases, so if you go to a
// page without a path alias, the breadcrumb will not display correctly
$urlsystem = drupal_lookup_path('source', $urlpathalias);
$urlsystemexplode = explode("/", $urlsystem);
$urltype = $urlsystemexplode[0];
$crumbpiece = ' » ';
// Uncomment this if you remove the Home crumb above
// if ($lvl == 1)
// $crumbpiece = ' ';
if ($urltype == "taxonomy") {
$term = taxonomy_get_term($urlsystemexplode[2]);
if ($lvl == count($url)-1) {
// Set to '' if you don't want to display current page's title
$crumbpiece = $crumbpiece . ' <strong>'.$term->name.'</strong>';
}
else {
$crumbpiece = $crumbpiece . ' <a href="' . base_path() .$urlpathalias.'" title="'.$term->name.'">'.$term->name.'</a>';
}
}
elseif ($urltype == "node") {
$node = node_load($urlsystemexplode[1]);
if ($lvl == count($url)-1) {
// Set to '' if you don't want to display current page's title
$crumbpiece = $crumbpiece . ' <strong>'.$node->title.'</strong>';
}
else {
$crumbpiece = $crumbpiece . ' <a href="' . base_path() . $urlpathalias.'">'.$node->title.'</a>';
}
}
else {
$urltitleexplode = explode("-", $url[$lvl]);
$words = array_keys($urltitleexplode);
foreach ($words as $word){
$urltitle .= ''.ucwords($urltitleexplode[$word]).' ';
}
if ($lvl == count($url)-1) {
// Set to '' if you don't want to display current page's title
$crumbpiece = $crumbpiece . ' <strong>'.$urltitle.'</strong>';
}
else {
$crumbpiece = $crumbpiece . ' <a href="' . base_path() .$urlpathalias.'" title="'.$urltitle.'">'.$urltitle.'</a>';
}
}
// Deal with underscores before returning
$crumbpiece = str_replace('_', ' ', $crumbpiece);
return ucwords($crumbpiece);
}
breadcrumbs from Menu path
breadcrumbs from Menu path http://drupal.org/project/menu_breadcrumb . this was exactly what i was looking for in the first place. for Drupal 6 only ...
This was such an awesome
This was such an awesome share... for anyone else who wants to use the above code but sees it not work, keep in mind that this person wrote the function url_breadcrumbs without the "s", so you would instead need:
<?php print url_breadcrumb(); ?>In your page.tpl instead of breadcrumb"s".
Actually is: <?php print
Actually is:
<?php print url_breadcrumb($breadcrumb); ?>Luis
French Characters not displaying properly
Hey guys, great function here, one thing is that i can't preserve the look of french characters, do you know where i need to make changes?
This is whats happening right now.
Intégration
turns into
Int%C3%A9gration
Thanks
it's been awhile since i did
it's been awhile since i did anything with international characters. i think it's something to do with utf8_decode() and utf8_encode()? they're PHP functions.
Sooo close (5.x)
Your snip was very close to what I wanted to do, but not quite.
After reading a ridiculous number of other posts trying to fix both breadcrumbs and menus for node level pages (this trick is generally considered impossible...) I came up with this ugly hack. If someone could roll this into a module, plus figure out how to invoke only on node level pages of certain types I would be happy to buy you a pizza :-)
It figures out where the node should live based on the clean URL, then uses menu_set_location to happily unroll the correct number of menus nested to an arbitrary depth, and posts a complete breadcrumb trail.
Caution: it runs on every single page, needed or not, regardless of type. Untested on taxonomy-centric sites.
Paste this into the bottom of your template.php :
<?php
//Node Path/Menu Repair based on pathauto + custom paths
//This should be a module, but I couldn't get it to work that way...
//And it should only work for specific content types, but I couldn't get it to work that way either...
function path2menu($node){
//Grab the URL
$uri_request = $_SERVER['REQUEST_URI'];
$urlexplode = explode("?", $uri_request);
$url = explode("/", substr($urlexplode[0], 1));
//so we have an array of url entities, no parameters, skip the opening slash
//we need to build the breadcrumb such that each entry adds to the one before..
//so [0] will be "animation", [1] will be "animation/profiles", etc
//[1] one should not be "profiles" on its own. We do this with $scratch in the loop below.
//echo $node->type; //debugging
//if($node->type == 'artist_profile'){ //content-type filter -- doesn't work without access to $node
//Build our faux hook_menu array
$crumbs = array(); //this will hold our menu items -- 'path', 'title'
$scratch = ""; //this will hold our slowly growing list
foreach($url as $item){
$scratch = $scratch . $item;
$thistitle = ucfirst(str_replace("-"," ",$item)); //hyphens to spaces, cap first letters. YMMV.
$thispath = drupal_get_normal_path($scratch);
$scratch = $scratch . "/";
$crumbs[] = array ('title' => $thistitle, 'path' => $thispath);
//uncomment to debug
//echo " title: $thistitle, path: $thispath ";
//housekeeping, mostly out of habit.
$thistitle = "";
$thispath = "";
}
//Pass it to menu_set_location() to open the menu and write the breadcrumb trail.
menu_set_location($crumbs);
//} //debugging for content-type if/then -- can't read $node from here, so it doesn't work.
}
path2menu($node);
?>
works in 5.x
The original version works for me perfect (5.x) - the others don't.
Thanks so much, custom_breadcrumb could not solve the simple problem of right paths and urls.
If You don't want to show "Home" on the frontpage simply solve it by the include in page.tpl.php (if it is not front print url_breadcrumb).
This is great! Thank you! :)
This is great! Thank you! :)
Simplified version
Here is my simplified version to accomplish this goal. I'm using 6.x and don't know if it will work in earlier versions.
In template.php:
function bcrumb() {$bcrumb = '<a href="/">Home</a> > '; // Start of breadcrumb. This creates a leading 'Home' link.
$dir_url = $_REQUEST['q'];
$pathArray = explode("/",$dir_url);
$crumbCount = count($pathArray);
for($i=0; $i<$crumbCount; $i++)
{
$checkPath = "";
for ($j=0; $j<=$i; $j++)
{
$checkPath .= $pathArray[$j];
if ($j < $i)
$checkPath .= "/";
}
$pathSource = drupal_lookup_path(source, $checkPath);
if ($pathSource) // If an alias doesn't exist for the current path the crumb is skipped, preventing mid-crumb blanks.
{
$nodeStrip = substr($pathSource,5);
$pageTitle = db_result(db_query("SELECT title FROM node WHERE nid = '$nodeStrip'"));
if ($i == ($crumbCount-1))
$bcrumb .= $pageTitle;
else
$bcrumb .= '<a href="/' . $checkPath . '">' . $pageTitle . '</a> > ';
}
}
print($bcrumb);
return true;
}
For your .tpl files, wherever you want the breadcrumb to appear: bcrumb();
One big difference in this code is it skips any level that doesn't have an alias. Spacing and capitalizing the word doesn't do any good if clicking the link gets you a page not found.
The site I wrote this for does not use taxonomy, so I have no idea if it will work properly on taxonomy pages.
---------------------------
Divi Creative Media
www.divicreative.com
Dave Vioreanu
Principal & Creative Director
Divi Creative Media, LLC
www.divicreative.com
I'm all taxonomy now, so I'll
I'm all taxonomy now, so I'll try it and let you know.