Free Trial

A Script For Breadcrumb Navigation

January 28, 2009 - 11:00 AM

Most web users are familiar with breadcrumb navigation. It can be useful when a site is organized in a hierarchical fashion. Yahoo! has detailed the typical problem and solution in their Design Pattern Library.

This short tutorial will provide a JavaScript that you can include in Markup Factory or any other web site. The script will be detailed here. It's pretty advanced, but if you follow the requirements set out here, you can just download it and put it on your site.

In order for this to be as simple as possible, there are some things that must be done in order for this to work. Fortunately, Markup Factory makes this easy. Here are the requirements:

  • The Prototype JavaScript Framework. We're fans of Prototype.js here at Markup Factory, and this script uses some of Prototype's features, which will be explained here.
  • The URLs of your pages must be hierarchical and each level must be a valid link. That means if you have a page located at /about/products/widgets/foo/, then /about, /about/products, and /about/products/widgets must also be real pages. This is easy in Markup Factory, as you can give a page any address you like.
  • When the script runs, it replaces underscores (_) and dashes (-) in the URLs to make the breadcrumb navigation. Using other characters and file extensions may result in the results not being as pretty as possible.
  • The end user must have JavaScript enabled. If they don't, no problem, they just won't see the breadcrumbs.

How it Works

The script does the following when the page loads:

  • Take the URL path and split its parts into an array, excluding empty parts.
  • If there are more than 0 parts, add a “Home” link to the root of the site.
  • Go through each part of the path and create a URL and a link.
  • Take the part and replace _ and - with spaces, then capitalize each word and make that the link.
  • Once that's complete, find a DIV on the page with an ID of “breadcrumbs” and replace its contents with the link you've created.

So, if your URL is http://gottung.net/my/page/for-the/bread_crumbs/test/, you'll get something like this:

 

Home > My > Page > For The > Bread Crumbs > Test

 

The code is in two functions. The first part extends the native JavaScript String to have a capitalize_each_word function:

String.prototype.capitalize_each_word = function () {
    var words = this.split(" ");
    var str = "";
    words.each(function (word, index) {
        str += word.capitalize()
        if (index !== (str.length - 1)) { str += " "; }
    });
    return str;
}

This demonstrates a powerful but controversial feature of the JavaScript language, often called Monkey patching. You can add methods to any object, even native ones. This should be done with extreme caution as it could create conflicts with other peoples' code and wreak havoc. This case seems pretty harmless, so let's go with it.

The next part is the actual function, which is placed inside a document.observe callback which fires when the DOM is ready. This means that when the page is downloaded and ready to go, then this script will start. Prototype.js uses this pattern to make starting your scripts a little easier.

The rest of the code isn't pretty, but it does exactly what was described earlier. The Prototype.js-specific functions used are: document.observe(), Array.without(), $, Array.each(), String.gsub(), and Element.update(). You'll also see our capitalize_each_word() function in action:

document.observe('dom:loaded', function () { 
    var output = "";
    var url = "";
    var path = location.pathname.split("/").without("");
    var div = $("breadcrumbs");

    if (path.length >= 1) {
        output += "Home > ";
        path.each(function (i, index) {
            url += "/" + i;
            i = i.gsub("[-|_]"," ").capitalize_each_word();
            if (index !== (path.length - 1)) {
                output += "" + i + " > ";
            } else { output += i; }
        });
    }
    if (div) { div.update(output); }
});

Including in Your Markup Factory Site

You can download this script below and add to a Template or Snippet. Somewhere in the page body, usually before the main content of the page, you'll need to put a DIV where the breadcrumbs will be inserted:



You'll usually leave this empty, but you can put whatever you want within the DIV tag. It will be replaced when the script runs.

Then, somewhere before the closing of the BODY tag, include Prototype.js (served from the Google AJAX Libraries API) and the script:



Upload breadcrumbs.js to your Files and you're ready to go.

Download the Script

breadcrumbs.js

Related Resources on the Web

Conclusion

We hope you were informed and enlightened by this example. Any comments would be appreciated, and help is always available at support@markupfactory.com. If you haven't yet experienced how Markup Factory can help you make a great web experience, try the demo. We hope you like what you see. If you do, sign up.

Response to A Script For Breadcrumb Navigation

  • chris said on May 21, 2009 - 8:18 AM

    Hi, great tutorial! I have it working (we are testing it now) BUT, I was wondering if there was a way, so that instead of the file name being shown "last" (it adds the whole file name, like monkeys.html) there was a way to: a) Show the file name without the ".html" in it? so instead of showing : Home>Animals>Monkeys.html It would show: Home>Animals>Monkeys b) Maybe even show the first 10 characters of the page's TITLE tag? So that, Home>Animals>Monkeys Would actually be: Home>Animals>Monkey Pictures. Makes sense?? I would greatly appreciate it if you could show me both :-) THANKS!!! Christophe

  • Nathan L Smith said on May 21, 2009 - 8:46 AM

    Chris, Thanks for your kind comments. Here are some suggestions. For both of these, you'll be working in the final "else" statement, because that handles the final item: the current page. > a) Show the file name without the ".html" in it? > so instead of showing : > Home>Animals>Monkeys.html > It would show: > Home>Animals>Monkeys In that else statement you can use a regular expression to remove the file extension: output += i.replace(/\..+$/, ""); That basically says, "replace a dot followed by one or more characters, followed by the end of the string with nothing." This is a reference sheet I use frequently: http://people.freebsd.org/~lofi/reference.html, and there are many other regular expression resources around, though you should be careful using them. Another approach would be to use the String's split method: output += i.split(".")[0]; This says, "split the string up into an Array of multiple parts, separated by dots, and get the first one. > b) Maybe even show the first 10 characters of the page's TITLE tag? For a client side script, you'll only be able to get the title tag for the current page, though we may add functionality to Markup Factory in the future that would generate breadcrumbs based on all of your page titles. In that same "else" statement, you just need to get the page's title. Easy enough: output += document.title; For just the 1st 10 characters you can use the substr method of the String. It takes 2 arguments: where the substring starts, and how long it should be: output += document.title.substr(0, 10); Hope that gets you closer to where you need to be. Thanks, Nathan

  • christophe said on May 21, 2009 - 9:18 AM

    Hi again Nathan, and thanks so much for both replying quickly and notifying me via email. OK! So, I got everything working, and it's awesome. Two other quick questions: a) Is that last line reffering to a google hosted script "necessary?" b) Where do you think would be the ideal location of the "bread crumb" showing? on the page? THANKS again! Christohe

  • christophe said on May 21, 2009 - 11:34 AM

    Just wanted to let you know: a) I've decided to put two bread crumb navigation bars -- if that is what they should be called -- one above and one below the fold :-) b) I was also able to modify the look of the path etc. using an external css file -- They look AWESOME. THANKS AGAIN for the great script, tutorial and help :-) I'll zap you an email when we go live with our updates. Christophe

  • christophe said on May 26, 2009 - 6:41 PM

    Hi again Nathan, Sorry to bother you again :-) I have one last issue that we have just discovered: When using a folder name that has a "space in it" Let's say /with images/ The following happens in the display: Home>With%20images>Here How could I remove the %20 from being displayed? THANKS!! Christophe

  • christophe said on May 26, 2009 - 7:22 PM

    I figured it out :-) I changed: i = i.gsub("[-|_]"," ").capitalize_each_word(); To: i = i.gsub("[-|_|%20]"," ").capitalize_each_word(); Works great !!

  • Nathan L Smith said on May 28, 2009 - 8:15 AM

    Christophe, Another way to do that would be to use a built-in JavaScript function: i = decodeURIComponent(i.gsub("[-|_]"," ").capitalize_each_word()); See http://www.w3schools.com/jsref/jsref_decodeURIComponent.asp Nathan

  • Fraulein said on December 1, 2009 - 1:26 PM

    Hey there, The breadcrumbs work nicely, and thank you so much for posting this. There is a little issue with my site- and I imagine it's something I did wrong. It isn't capitalizing the words, nor is it removing the _ or - in my file names. I did add your line above that removes the file name extension, and that worked beautifully. Any thoughts? I do have quite a few scripts running in the page already- maybe a conflict? Thanks, Andrea

  • Nathan L Smith said on December 1, 2009 - 4:06 PM

    Fraulein, Let us know what page it's running on and we can take a look. Nathan

  • Brent said on March 15, 2010 - 12:38 PM

    Hi. I am having the same issue that Fraulin was having. The - and _ is still showing up. Here's the link to what I have up as a test. http://www.wccwebmaster.com/bread-crumb-test/bread_crumb_test_2/bread-crumb/breadcrumb/ Thanks for any help you can provide.

  • Nathan L Smith said on March 17, 2010 - 10:59 AM

    Brent, Looks like it works if you replace the String with a regular expression literal on this line: i = i.gsub(/[-|_]/," ").capitalize_each_word(); This may be related to differences from Prototype 1.6.0 -> 1.6.1. Let us know if that works for you.

Leave a Comment

Required, but not displayed.

Copyright © 2007 - 2009 Cramer Development. All rights reserved.Terms of ServicePrivacy PolicyFAQContact Us