"Excuse me please. My ear is full of milk..."

– Oliver Hardy, Going Bye Bye (1934)

Skip on down to the menu.

"You Are Here" Perl Menu

Here's a you are here menu that I whipped up one afternoon. I liked it so much that I use it on all my web sites.

Include it at the top of your pages to add an extra measure of usability.

Remember that you must have an index.shtml or some such file in *every* directory in your website. That way users won't get any "403 Forbidden" or similar errors. This requires some amount of dicipline and planning, but the usability benefits are more than worth the extra effort.

If you don't want to do this — I don't always for intranet sites — you can use the auto index feature of your web server and allow users to browse all directories in the web server space. You can then include the "you are here" menu in the header portion of your auto index template, so that even when the user gets an automatically generated index page, the navigation paradigm is not broken.

How to include

Using Apache SSI

Use the following line in your .shtml files wherever you want the menu to appear.

You may need to adjust the path as required by your web server setup.

<!--#include virtual="/cgi-bin/youarehere.pl"-->

The Code

#!/usr/bin/perl
#  youarehere.pl
#  Revision 2004-10-05, TAS
#
#
# Put a "breadcrumb trail" of links at the top of each web page.
#   Creates a series of links such as ...
#        [ Home > departments > engineering ]
#    at the top of each web page so that you always know where you are
#    and can easily get back to a higher level in the web site structure.
#
#    Written by Tom Sneddon on March 12, 2004
#
# Revision History:
# Revision 2004-03-12:
#        Tom Sneddon
#        Initial Release
# Revision 2004-03-24:
#        Tom Sneddon
#        Replaced %20 and spaces with &nbsp; in $referrer.
#        Replaced &nbsp; with %20 in $url.
# Revision 2004-03-27:
#        Tom Sneddon
#        Added show underscores option.
#        Added show extensions option.
# Revision 2004-05-24:
#        Tom Sneddon
#        Fixed situation where REQUEST_URI contained http://domain_name
#          at the beginning.
# Revision 2004-10-05:
#        Tom Sneddon
#        Fixed bugs in the menu print commands.  I can't believe that I
#          used ">" instead of "&gt;"!  I know better than that...
#        Added more documentation to variable initialization section.
#        Tweaked regular expressions some.
#

use strict;                          # Require good programming practice
use CGI qw(:standard);               # Use the CGI module
use CGI::Carp qw(fatalsToBrowser);   # View fatal errors in the output text stream

print "Content-type: text/html\n\n"; # Print the http header

# Initialize variables -- binary variables are "false", and "true" for true
my $show_filenames = "true";         # Show the filename as the last entry in the menu.
                                     #   If you don't set this to "true" each file in a
                                     #   given directory will have the same menu displayed.
my $show_top_link = "false";         # Make the top level menu entry a hyperlink.
                                     #   Usually "false".  Why would you link to yourself?
my $show_underscores = "false";      # Show underscores in path and file names of menu text.
                                     #   If set to "false", non-breaking spaces will
                                     #   be used in place of the underscores.
my $show_extensions = "false";       # Show the file extension of filenames displayed
                                     #   in menu text.  The menu generally looks cleaner
                                     #   if this is set to "false".
my $referrer = $ENV{'REQUEST_URI'};  # This is the url of the page that invoked the program.
my $domain = $ENV{'HTTP_HOST'};      # This is the domain name of the http server.
my $link;                            # A variable to store a link name.
my $home_link = "Home";              # What we call our home page link.  This is the
                                     #   text that displays for the first entry
                                     #   in the menu.
my $menu_classname = "pagemenu";     # CSS class name for the menu.
my $script_directory = 'cgi-bin';    # Don't display the menu if this is in the url.
my $remainder;                       # Whats left of a line after splitting it.
my $output;                          # The output html of this program.

# Don't do this if we're inside a script directory
unless ($referrer =~ /$script_directory/) {
  # Replace all spaces and %20 (encoded spaces) in the url with html non-breaking spaces
  $referrer =~ s/%20| /&nbsp;/g;

  # Show or not show filenames as the last item in the menu (not case sensitive)
  if ($show_filenames =~ /false/i) {
    ($referrer, $remainder)  = split /\/\w*\.\w*$/, $referrer, 2;  # Eat the filename and extension
  }
  #print '<p>', $referrer, '</p>', "\n";                   # Use this line for debugging
  $output = "<p class=\'$menu_classname\'>[&nbsp;<a href=\'http://$domain\'>$home_link</a>";
  $remainder = $referrer;                                  # Default value to start with
  my $url = "";                                            # Url of a link
  $remainder =~ s!^(http://)!!;                            # Get rid of any leading "http://"
  $remainder =~ s!^.*?/!!;                                 # Get rid of any leading "domain.name/"
  # Split the url into parts and process each one as a link
  while ($remainder) {
    ($link, $remainder) = split /\/|\\/, $remainder, 2;    # Grab the first link in $remainder
    $url = $url . '/' . $link;                             # Append it to what is in $url so far
    $url =~ s/&nbsp;/%20/g;                                # Replace non-breaking spaces with %20 in url
    if ($show_underscores =~ /false/i) {
      $link =~ s/_/&nbsp;/g;                               # Replace _ with space for text in menu
    }
    # Do this only if this is not the last link
    if (($remainder) or ($show_top_link =~ /true/i)) {
      # Make this item a hyperlink
      $output = $output . " &gt;&nbsp;<a href=\'http://$domain$url\'>$link</a>";
    }
    # Do this if we are on the last link
    else {
      if ($show_extensions =~ /false/i) {
        $link =~ s/\..*$//g;                               # Remove filename extension
      }
      $output = "$output &gt;&nbsp;$link";                 # Don't make the last item a hyperlink
    }
  }
  $output = "$output&nbsp;]</p>\n";                        # Add the ending "]" to the menu
  print $output;                                           # Print our output to the web page
}