Page 1 of 1

Setting up a breadcrumb

Posted: Thu May 31, 2007 6:33 am
by Stryks
I'm trying to add a breadcrumb nav to an existing site, but I'm finding it a bit harder going than I had expected.

Mostly, the page flow runs: Home > Search Result > Brand > Customise or > Order

My issue in this regard is that you can also get to brand from the Brand Listing page. So what if someone bookmarks a brand (I set it up so they can and should if they like) .... what back branch should be set?

From Home, Login or Sign Up are also options, and then there is Admin and all the branches under that.

I've tried to set it up dynamically, but I cant figure dynamic backbuilding for pages accessed directly, and I also cant figure out how to avoid issues with people manually jumping steps. For example, getting to the Brand page and then using the address bar to get into one of the admin pages. The dynamic method I came up with just adds itself onto the end of the existing trail.

Heres what I had tried.


Code: Select all

function getBreadCrumb($current_name, $current_link) {
	if(!isset($_SESSION['BC_NAV'])) $_SESSION['BC_NAV']['Home'] = "index.php";
	if(!in_array("index.php", $_SESSION['BC_NAV'])) {
		// Add element to the end of the breadcrumb array
		$_SESSION['BC_NAV'][$current_name] = $current_link;
	} else {
		$found = false;
		foreach($_SESSION['BC_NAV'] as $name=>$link) {
			if($found) unset($_SESSION['BC_NAV'][$name]);
			if($name==$current_name) $found = true;
		}
	}
	// Construct final breadcrumb trail
	$final_element = end($_SESSION['BC_NAV']);
	foreach($_SESSION['BC_NAV'] as $name=>$link) {
		if($link==$final_element) 
			$new_bc[] = "<em>$name</em>";
		else
			$new_bc[] = "<a href=\"$link\">$name</a>";
	}

	return "<strong>You are here:&nbsp;</strong>" . implode(" > ", $new_bc);
}

Re: Setting up a breadcrumb

Posted: Thu May 31, 2007 7:32 am
by feyd
Stryks wrote:My issue in this regard is that you can also get to brand from the Brand Listing page. So what if someone bookmarks a brand (I set it up so they can and should if they like) .... what back branch should be set?
Home.

Posted: Thu May 31, 2007 9:54 pm
by Stryks
Ive been thinking and tinkering and this is where I'm at.

I switched it over to a class, mainly because I like the way I can encapsulate functionality into one location. I'm still learning though, so if anyone has any improvements on class implementation, I'd appreciate that also.

class_breadcrumb.php

Code: Select all

class breadcrumb {
	// Class Variables
	var $intro = "You are here: ";	// Configuration: Breadcrumb lead-in text
	var $spacer = " > ";					// Configuration: Breadcrumb delimiter
	var $base_link = "index.php";		// Configuration: Base crumb URL	
	var $base_text = "Home";			// Configuration: Base crumb text
	
	var $output;							// Holds breadcrumb output string
	var $this_page_name;					// Holds the current levels text - for headings or whatever
	
	function breadcrumb($base_link = "index.php", $base_text = "Home") {
		if(!isset($_SESSION['BC_NAV'])) $_SESSION['BC_NAV'][$this->base_text] = $base_link;
	}
	
	function add_level($new_link, $new_text, $parent_link = false) {
		if(!isset($_SESSION['BC_NAV'][$new_text])) {
			// Add a new child to the breadcrumb tree
			$_SESSION['BC_NAV'][$new_text] = $new_link;		
		} else {
			// Clip any items after the current one
			while(end($_SESSION['BC_NAV']) != $new_link) array_pop($_SESSION['BC_NAV']);
		}
		// If $parent_link is set, make sure the new level is a direct descendant or shortcurcuit to base crumb 
		if($parent_link) {
			$parent_found = false;
			foreach($_SESSION['BC_NAV'] as $crumb_text=>$crumb_link) {
				if($parent_found) if($crumb_link != $new_link) unset($_SESSION['BC_NAV'][$crumb_text]);
				if($crumb_link == $parent_link) $parent_found = true;
			}
		}
		$this->generate();
	}
	
	function generate() {
		$final_element = end($_SESSION['BC_NAV']);
		foreach($_SESSION['BC_NAV'] as $crumb_text=>$crumb_link) {
			if($crumb_link==$final_element) {
				$new_bc[] = "<em>$crumb_text</em>";
				$this->this_page_name = $crumb_text;
			} else
				$new_bc[] = "<a href=\"$crumb_link\">$crumb_text</a>";		
		} 
		$this->output = $this->intro . implode($this->spacer, $new_bc);
	}
}
This solves alot of issues for me, though I still dont know if it's the best solution.

On index.php I call

Code: Select all

// Start breadcrumb tracking
	require_once(PATH_CLASS . "class_breadcrumb.php");
	$bread = new breadcrumb();

	// Reset breadcrumb though not shown
	$bread->add_level("index.php", "Home");
Then on login.php I start with

Code: Select all

// Start breadcrumb tracking
	require_once(PATH_CLASS . "class_breadcrumb.php");
	$bread = new breadcrumb();

	// Add breadcrumb
	$bread->add_level("login.php", "Member Login");
... and show the result with ...

Code: Select all

<div id="page-bread"><?php echo $bread->output; ?></div>
Also, by calling it with the parent set, I can force pages not under an appropriate parent to go back directly to home.

Code: Select all

// Add breadcrumb
	$bread->add_level("admin.php", "Account Management", "index.php");
Any comments or advice welcome.