Breadcrumbs are things you bake with and, if you've read the Hansel and Gretel fairy tales they are what Hansel uses to mark their path in the forest. On a website, breadcrumbs indicate the "path of navigation," that is to say, it's a list of where you have been recently.

The natural question is to ask "why bother?" It seems like such a hassle to add a seemingly useless function. There are a couple of schools of thought on this; one is that a breadcrumb trail improves interclickability in your site and allows for easier navigation. The other is that its fairly unique, and if implemented properly can give your website a nice touch. Indeed, you do not see very many websites that use breadcrumbs and on my personal website the reaction was a resounding "Wow! Nice touch, Lisa!"

Here on E2 you can see breadcrumbs in action by changing your user settings, with the Recent Nodes nodelet.

To implement a breadcrumb trail on my own website I opted to use PHP and memcached. Memcached is easier than using sessions since it allows persistance without heavy cookie usage, though this still relies on cookies.

You'll need to put this bit in the top of every php page:


session_start();
session_register("bread_uid");
if (is_null($_SESSION['bread_uid']))
	$_SESSION['bread_uid'] = uniqid("breadcrumb:");
require_once("breadcrumb.class.php");
require_once("MemCachedClient.inc.php");
$cache = new MemCachedClient(array("servers" => array("your memcached server here:11211"),"debug"=>0));
$crumb = new Breadcrumb(array("memcache_link"=>$cache,"max_crumbs"=>5,"id"=>$_SESSION["bread_uid"]));

To add and print pages, simply use the following snippet. You will note that if you add a crumb before printing you will print the current page in your list.


$crumb->print_crumbs(); 
$crumb->add_crumb("this page's title",$_SERVER['PHP_SELF']);

Below is breadcrumb.class.php. It has three public functions including the constructor. add_crumb() and print_crumbs().


<?php
/***************************************************************************
 *            breadcrumb.class.php
 *
 *  Fri Feb 20 01:41:50 2004
 *  Copyright  2004  Lisa Seelye
 ****************************************************************************/

/*
This file is released under the BSD license
*/
require_once("MemCachedClient.inc.php");
class Breadcrumb {

	var $memcache_link; // A link to a memcached resource
	var $breadcrumb;  // list of breadcrumbs
	var $max_crumbs; // max number of crumbs to save
	var $id; // this particular user's unique id
	
	function Breadcrumb($options = 0) {
		if (is_array($options)) {
			$this->memcache_link = $options['memcache_link']
			$this->id = $options['id']
			$this->max_crumbs = $options['max_crumbs']
		}
		if (!is_null($this->memcache_link)) {
			$this->_init_cache();
		}
	}
	function add_crumb($title,$url) {
		/* Add a crumb to the list.
		 * $title is the title of the page
		 * $url is the URL of the page
		*/
		
		$shift = array("title"=>$title,"url"=>$url);
		if (sizeof($this->breadcrumb) > 0) {
			array_unshift($this->breadcrumb,$shift);
			if (sizeof($this->breadcrumb) > $this->max_crumbs) {
				array_pop($this->breadcrumb);
			}
		}
		else {
			$this->breadcrumb = $shift;
		}
		$this->_update_cache();
	}
	function print_crumbs() {
		printf("<ol class=\"bread_list\">\n");
		foreach ($this->breadcrumb as $index=>$crumb) {
			printf("<li class=\"bread_list_element\"><a class=\"bread_list_link\" href=\"%s\">%s
			</a></li>\n",$crumb['url'],$crumb['title']);
		}
		printf("</ol>\n");
	}
	function _init_cache() {
		if (!is_null($this->memcache_link)) {
			$this->breadcrumb = @unserialize($this->memcache_link->get($this->id));
			if (!is_array($this->breadcrumb)) 
				$this->breadcrumb = array();
		}
	}
	function _update_cache() {
		if (!is_null($this->memcache_link)) {
			$this->memcache_link->set($this->id, @serialize($this->breadcrumb),time() + 86400*2);
		}
	}
}
?>

I have included the classes on each element in the print_crumbs() function to allow the user to define their own styles via a style sheet. The styles are: