PDA

View Full Version : Making a breadcrumb in PHP


erisco
11-12-2006, 12:50 AM
Breadcrumb script download (http://pack.abstractflow.com/php/breadcrumb/breadcrumb.zip)
It was too big to have posted here!

Usage and Examples

If you have not already, download the breadcrumb script and take a look at the documentation already included in the README. Many of the options left at default will be fine. I will explain the usage of what are likely to be the popular options. The descriptions provided in the download should suffice for the ones I do not talk about, however. To get a feel as how customization works, try calling the function without anything special like this:

<?php
echo breadcrumb();

The echo, or print, is required because breadcrumb() returns a string. It does not output the breadcrumb itself. Now, lets change the separator by changing the separator option.

<?php
echo breadcrumb(array('separator' => '/'));

Now, instead of the double angle bracket, a forward slash appears between each link. By default the link back to the root of your site is called Home. We can change this through the home_link option.

<?php
echo breadcrumb(array('home_link' => 'Index', 'separator' => '/'));

Now the first link appears as Index rather than Home. Note, the order of the options does not matter. We could have also defined the options in an associative array assigned to a variable, and then passed that variable to the function. This will be ideal if you have many options to change.

Often, sites have extensions on the URIs such as /page.php, where .php is the extension. This will produce a link in our breadcrumb that will look like page.php, which is sometimes undesirable. We can have the extension removed by setting the rm_file_ext option to true.

<?php
echo breadcrumb(array('rm_file_ext' => true));

The last, most useful, options are the templates. These specify how each link is outputted. This is useful if you are not necessarily outputting HTML, or you need to add a class to each anchor tag, or whatever the case may be. We have three templates to make use of: the "first_tpl", the "tpl", and the "last_tpl". The first_tpl is applied to the first link in the breadcrumb, which is always your home link. The tpl template is applied to every link after that except for the last link, where the last_tpl is used. Typically, you only care about about the "tpl" template.

<?php
$options = array('tpl' => '<a href="%s" class="breadcrumb_link">%s</a>');
echo breadcrumb($options);

Each template uses string formatting to specify where the link and where the link text are inserted. If you are not familiar with string formatting, check out http://php.net/sprintf. If you need to insert the values in reverse order, or you need to insert each one multiple times, make use of numbered placeholders. The link is argument 1, and the link text is argument 2. Example:

<?php
$options = array('tpl' => '<a href="%1s" onclick="return popup(\'%1s\')">%2s</a>');
echo breadcrumb($options);

Where first_tpl and last_tpl come into use may be with CSS styling. Let's pretend that we want dividers between each breadcrumb link, so we use the border-left css property to achieve this. However, it looks silly to have the first link with a border to the left of it. We can repair this by using first_tpl to specify it has a class named "first_link" that sets the width of the left border to zero.

<?php
$options = array('first_tpl' => '<a href="%s" class="first_link">%s</a>');
echo breadcrumb($options);

And that concludes the mini-tutorial of how to use my breadcrumb function. If you are still confused, please make sure you have read the documentation included in the README. If that does not help, feel free to leave a post below and I will try to answer your question the best that I can.

New features!

Package Update Dec 27, 2008: The documentation is now in a README and the breadcrumb.php file received a few changes. None should break BC other than the new default formatting. If this new default formatting is in the way, please let me know.

Feature Added Dec 27, 2008: You can now provide a callback to format your link text. By default a formatter that replaces hyphens and underscores with spaces and capitalizes all words is included. If you do not want this functionality, pass a callback that simply returns the string unchanged. This new option is called "format_callback". Ex:

<?php
$format = create_function('$s', 'return $s;');
echo breadcrumb(array('format_callback' => $format));

This should address issues raised by pschena.

Where did the old post go???
This breadcrumb function has received a fair bit of popularity and I felt it necessary to address a few issues I have been getting emails about.

This script does not adapt to all breadcrumb schemes.

When I originally wrote the breadcrumb function (the ones that used to be listed below, removed in favour of the new version) I had a fair bit less experience with PHP than I do now. I fixed most of issues with the function's design with my "new breadcrumb script" which was offered via download from my web site as a zip (a link used to be here, still is). However, the primary issue is that it is not practical to create a function to adapt to every breadcrumb scheme. While I offered quite a bit of configuration, there is bound to be case after case where it isn't enough. For simple, run of the mill PHP powered web sites, this function will likely do its job. For more complex applications it is likely to hit some snags. So keep in mind that while I attempted to cover a reasonable amount of possibilities, I did not cover every single one. If you are struggling getting my function configured to work for you, it may just be easier to create your own solution.

One of the biggest hurdles for using my breadcrumb function is if the URI does not actually reflect the breadcrumb you want to generate. The data that should be used to generate the breadcrumb may come from other sources. This is quite common in sites using rewriting or get or post data to pull up pages. For example, consider this:

http://www.example.com/pages.php?page=portfolio

The best breadcrumb you are going to get is something like:

Home >> pages

Which is obviously not what you want. The links will work properly, but the link text is suboptimal. I could add an option that would allow you to specify something like:

array('pages' => 'Portfolio');

But that will only work in situations where the number of hooks given by the URI is equal to the amount of links you really need in the breadcrumb. Let's consider this scheme:

http://www.example.com/view.php?catid=493

However, category 493 is actually a sub category of a sub category of a category. So while we could use the config array to turn

Home >> view

Into...

Home >> LCD Monitors

But we really need...

Home >> Electronics >> Displays >> LCD Monitors

Now we have yet another problem. Not only are there not enough hooks, there is no way to specify the links associated with them. You could specify the needed breadcrumb as an associative array, perhaps, such as:

array('Home' => '/',
'Electronics' => '/view.php?catid=200',
'Displays' => '/view.php?catid=302',
'LCD Monitors' => '/view.php?catid=493');

However, if this were the case, you could easily transverse the array yourself. By the time you solve the issues associated with my limited breadcrumb function, you find yourself not needing of it anyhow. The function is targeted towards a particular use-case where the data needed for the breadcrumb is in the URI. For example, HTMLForums's URI scheme should work fine because of their use of URL rewriting. Our /view.php?catid=xxx example could be fixed with rewriting, and we could have /electronics/displays/lcd-monitors/. The breadcrumb function would work fine with that as well. Such uses of rewriting are also very beneficial to SEO. Not every rewriting scheme is that simple though, and it will not always result in a form that works nicely with my breadcrumb script. Again, it is not practical to adapt to every rewriting scheme either.

That said, if you have any suggestions, improvements, or questions for this script please let me know via private message or a post below. I hope that this script continues to solve many breadcrumb'ing needs.

platey
11-17-2006, 12:34 PM
Beautiful PHP!

this is exactly what ive been looking for, thank you!

my only questions regarding this code -

is there anyway you can code it to hide or take off the .php suffixes when it displays it back to the viewer/user? which leads me towards this question: on the Home page is there any way that the code can take away the index file rather than have it display this 'Home / index.php'??

also, my css doesnt seem to have any affect to the script, regarding positioning, once pulled in.

thanks again though!

erisco
11-18-2006, 12:31 PM
Here is a script with your desired modifications

Removed -- script was not robust enough to continue publishing. Use the new version. Download link is in the OP.

I didn't put the addons into the passed arrays, I didn't feel there would be a need to because all servers should only have one permitable filename for your index/home/default or whatever. Also most web masters or developers typically keep the same file extensions and don't mix up .php and .html and .htm and the whatnot.

If you want your CSS to work with it, try this call:

echo '<span class="breadcrumb">'.breadcrumb().'</span>';

Now in your CSS you can do the following:

.breadcrumb A:link, .breadcrumb A:visited, .breadcrumb A:hover, .breadcrumb A:active {
text-decoration:underline;
color:#333;
}
.breadcrumb A:hover {
color:#990000;
}

Just for example. You can output whatever you want around the breadcrumb for customized appearance.

I hope this helps!

platey
11-20-2006, 05:34 AM
Seriously erisco, this is brilliant!

Thank you for this, and i hope someone else will stumble across this code and find it as useful as i did!

Mac
03-21-2007, 06:39 PM
I literally just stumbled upon this code....absolutely brilliant.

erisco
03-21-2007, 07:13 PM
Great to see the script came into good use! Thank-you for the compliments. To better the script I sped up a couple of the strings, but the main improvement was dropping the need for preg_replace() to slice off query strings which will use the regex engine. Although the new alternative using a few more, yet faster, functions isn't as perfect it will certainly still do the job. If anyone has problems with this change please let me know and I can rework a solution. Also keep note that only the original script changed and not the one platey requested.

Thanks!
erisco

robin1
03-24-2007, 11:42 AM
Hello,
I'm new to php and i'm working on a small classified script for my website. I'm trying to add the script you posted here and could use some help.
right now i'm testing the scrip on my local PC(apache,php,mysql).

the script works awesome but not sure how to modify to fit my classified script.
folder the php scripts are located: http://192.168.0.101/classified/

http://192.168.0.101/classified//index.php , i added the breadcrumb function:
breadcrumb('Classified', ' >> ', false, false)

after running it it displays the the following:
Classified >> Classified >>
how do i just display the classified rather the the url and classified i entered in the breadcrumb?

sec problem:
when i click on a category it goes to page_2 (as it should) but it displays:
page2 >> Classified >> Page_2.php?subcat=Housing
it moves page2 to the beginning and classified(which is the main page) to the sec spot?

any help you can give me would be greatly appreciated.
Thanks
robin

Paul
03-24-2007, 03:19 PM
Looks like google picked up on this, just search for breadcrumb PHP and this post comes up toward the top. Congrats erisco, you are famous :).

johnz
03-26-2007, 12:21 AM
Great stuff erisco! I'm sure this will be helpful for many people.

erisco
04-02-2007, 10:43 PM
robin1, the script relies on splitting the url at forward slashes. In the url http://192.168.0.101/classified//index.php there is a double forward slash which is probably the culprit. The other problems may have cascaded from this.

If the url must contain two forward slashes, for whatever reason, do a realpath() call on $_SERVER['REQUEST_URI'] so that the line looks like this:

$whole = $_SERVER['HTTP_HOST'].realpath($_SERVER['REQUEST_URI']);
And that should clear it up.

Paul, wow, that is pretty neat :D I don't think I have ever had something less than six keywords long appear on the first page of Google before heheh.

johnz, thanks, happy PHP'ing!

sugar_lisx
04-28-2007, 04:18 PM
hey, That code is the only code that works for me!
Is there a way of labeling the directories? So it doesn't come up as the file name? If that makes sense?
thanks

scoutt
04-29-2007, 07:45 PM
Just to note erisco, and for anybody that uses IIS with php, this script will not work. Apache is required for it to work. The reason is that IIS does not populate $_SERVER['DOCUMENT_ROOT'], which will fail in this script.

Otherwise good job erisco.

erisco
05-02-2007, 10:09 PM
Sorry, here is a fix:


<?php
if (!isset($_SERVER['DOCUMENT_ROOT'])) {
$_SERVER['DOCUMENT_ROOT'] = substr($_SERVER['SCRIPT_FILENAME'] , 0 , -strlen($_SERVER['PHP_SELF'])+1 );
}
?>
Which was a solution taken from: http://ca3.php.net/reserved.variables
So, if this one doesn't work, there are more on there.

Damn IIS :P

Miriam
05-04-2007, 03:24 PM
Thank you, this script is great. I have only one question. I have my index.php in the root and all other files are in folders. The breadcrumb script prints also the name off the folder. Is there a way to not show the foldername in the breadcrumb?

Example:
I have a file contact.php in the folder pages. The breadcrumb prints: Home>pages>contact

I want the pages removed from the printout, but not from the link offcourse. Is this possible?

erisco
05-08-2007, 09:42 AM
sugar_lisx, you mean "masking" the real directory names with something different?

Miriam, yes. The portion...
$whole = $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
Defines what is split up into the braedcrumb. In your case you would define it yourself and exclude pages/.
$whole = 'http://localhost/'.$page;
Where $page is the name of the page you are loading out of pages/... however that is specified.

rh-penguin
05-08-2007, 11:52 AM
Nice script!

erisco
05-08-2007, 04:52 PM
Sugar, could you explain more?

Miriam,
$whole = $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
can be replaced with whatever you desire.
$whole = 'http://www.example.com/'.$page;
Where $page is the page you want from pages/... however that is obtained.

pschena
09-10-2007, 12:54 AM
Found this on Google, and looks very handy.

Just a quick question; would it be appropriate to use this code for dynamic page titles?
How could it be re-purposed?

Would it be possible to alias a folder name so that if it was called 'folder-name' in the page title it could appear as 'Folder Name'?

Thanks in advance.

sgt.bilko
09-13-2007, 03:52 PM
Hi erisco,

I am new to php, and probably being a bit of a nunce, that said however, I had read through the comments and can't see what I would like to do. Following on from the modifications you made for platey by stripping the .php from the individual file names, is it possible to remove the link from the file if it is not index.php?

To make it clearer, using your example:

Home / Foo / Bar / file.php

can you remove the link from file.php?

Many thanks for a great script.