When users browse your web site, there is the a tendency to get lost in all of
the information present. This poses a larger problem when get past a few
dozen pages. As pretty much all really good sites have lots of content, it's
important to make navigation as easy as possible; lest the users get fed up
with your site because they are constantly lost!
So, Microsoft, in their infinite wisdom, provided the Content Linking component. While this is a good tool for making web pages act like book pages, it really doesn't address following where the users are/have been. Also, it's not terribly dynamic. You, the web site developer, have to pre-define the order of the pages, how they should be listed, and fix their URLs... Not particularly nice if you move things around much, since you have to fix the linking file every time you do it.
Then Microsoft, in their FrontPage product, allowed you to create dynamic navigation bars. This was a lot better concept, but it has a few flaws. Unless you want to waste a bunch of space on your pages displaying the navigation text/icons/buttons there isn't much of a choice. Also, the editor for the relationships doesn't track with the links for the documents. So, once again, every time you move things around you also need to move them in the Navigation Bar view to match.
You will probably be more than slightly happy to know that there is a solution to this annoyance. Better yet, it's completely coded in VBScript running under ASP! Not only does this mean that it's a cinch to set up, but it's also completely customizable.
So, without further ado, let's dive in and have a look at what's involved.
Step 1: Install the GLOBAL.ASA file. If you don't know what the
GLOBAL.ASA file is, then you're probably very new to writing applications using
ASP. The GLOBAL.ASA file allows you to trigger four events. These are when
the Application (your web site) starts/stops and when Sessions (a user login
at run-time) start/stop. For the purposes of doing content tracking, we need
to have each session's data separate. Therefore we will be installing a
GLOBAL.ASA file with the Session_OnStart and Session_OnEnd routines defined.
If you already have a GLOBAL.ASA file, then you will need to insert the few
statements provided into it. Please look in the GLOBAL.ASA file provided.
The purpose of the statements are to define the HistLog dictionary and
HistCount session variable. "HistLog" will be used to hold the data
representing where we have been and HistCount specified what is the last
key added to HistLog.
Step 2: Install and customize the HISTMAINT.INC and HISTSHOW.INC files.
These are the include files which make all of the magic happen. We'll discuss
what's inside HISTMAINT.INC in a moment. For simple text linking, there is
*no* customization that needs done in HISTMAINT.INC, unless
you want to add additional items in the list. More on that later.
Unfortunately, there is significant work do be done in HISTSHOW.INC; because
it is responsible for formatting the content of HistLog into what you want
to display to the user. Let's take a moment and look inside HISTSHOW.INC to
see what needs done:
<%
'HistShow.inc - Show the entries in the History List
'***************************************************************
'NOTE: This module should be modified to format the result
' data in the necessary fashion to be properly displayed on
' *your pages*! Remember to handle any additional ThisXXX
' entries here, or things will get really ugly!
dim HistArray
dim HistURL, HistText
'Dim any additional data entries for ThisXXX as HistXXX here!
HistArray = Session("HistLog").Items
HistPtr = Session("HistCount")
Response.Write("History Counter is " & HistPtr & "<br>")
for i = 0 to HistPtr - 1 step ItemCount
HistURL = HistArray(i)
HistText = HistArray(i + 1)
'Restore any additional ThisXXX entries as HistXXX here!
'Example line below is for each ThisXXX entry
' note the index change!)
'HistXXX = HistArray(i + 2)
Response.Write(HistText & " at URL <a href=""" & _
HistURL & """>" & HistURL & "</a><br>")
next
%>
The first Response.Write that you see isn't necessary, and should be removed.
It's sole purpose in life is to let you know that HistCount (locally referenced
as HistPtr) is being properly maintained. When you are using this tool on
your pages, it would look really ugly to show this value to the users! Our
other Response.Write is what actually makes the list available to the users.
How you choose to format the list is completely up to you! If you've seen
Netscape's site with the neat dynamic navigation links at the top of their
pages, you could do much the same thing with something like:
Response.Write(" > <a href=""" & HistURL & """>" & HistText & "</a>")
Think about what you want to make the Content List look like, try making a
static version of it in your HTML editor, then substitute HistURL, HistText
etc and slap it into Response.Write. With a little experimentation, you can
achieve just about any look you desire. For those of you who want to do neat
stuff this is the first place we would need to modify in order to add
additional things, like an image URL for those of you who want to be able to
display pretty buttons instead of just plain old text. You would, for
instance, DIM a new variable as HistImageURL to hold the URL, then restore
it's value using something like:
HistImageURL = HistArray(i + 2)
Remember that if you're adding more than one extra item, you'll need to increment the value added to i for each one. That's all there is to be done inside HISTSHOW.INC. I'm sure you've had worse tasks to do!
Step 3: Update your ASP pages to use HISTMAINT.INC and
HISTSHOW.INC.
This isn't anywhere near as bad as it sounds. For each page you wish to add a
link on, there are two things which need to be added. And for each page that
you wish to display the Content List on there is one thing to be added. You
can look at the four ASP pages included for inspiration as to what needs done.
Let's look at what is included in the START.ASP page provided. In the HTML
<HEAD>
section goes the code to set up where we are, and an include for HISTMAINT.INC:
<%
Dim ThisURL, ThisText
'Dim any additional data entries for ThisXXX here!
ThisURL = "http://" & Request.ServerVariables("SERVER_NAME") & _
Request.ServerVariables("PATH_INFO")
ThisText = "Start Page"
'Set any additional data entries for ThisXXX here!
%>
<!-- #include virtual="/{your include path}/HistMaint.inc" -->
The DIM statement is used to define the variables that we will be providing
to HISTMAINT.INC. ThisURL is the URL of the page we want to link to.
Usually we would want to come right back to here, so the default code shown
actually generates a valid URL from the Request.ServerVariables collection.
ThisText is the displayed text you would show to the user. This is another
place we would need to modify in order to add additional things, like an image
URL. You would, for instance, DIM a new variable as ThisImageURL to hold the
URL, then define it's value using something like:
ThisImageURL = "http://" & Request.ServerVariables("SERVER_NAME") & "/images/button1.gif"
After that, we need the include tag to make the magic happen. Obviously, the {your include path} should be replaced with wherever you place the include files on your server.
That covers maintenance of HistLog and HistCount. That wasn't too painful,
was it? But, you know, that just maintaining the list isn't enough. We have
to display what this list holds in store for us. That's even easier. All we
need to do is include the reference to HISTSHOW.INC where we want the output to
be placed. Once again, let's look inside START.ASP:
<!-- #include virtual="/{your include path}/HistShow.inc" -->
Yes... you have to fix the {your include path} here aswell. If you are going to use plain text for your output, that's all the editing that each of your ASP pages requires. Simple? You bet!
Perhaps we should look into how HISTMAINT.INC works in a little more detail.
We're going to look at the overall process that HISTMAINT.INC performs, not
the specific code used. The HISTMAINT.INC, HISTMAINT.INC and START.ASP have
been well documented to show you where specific things are happening, and also
how to customize some of the aspects of it's operation.
We start by determining if the list is empty. Oh dear! When a user first accesses a page with this code, the list will be empty. It's a perfectly normal condition to have. In this case, we simply insert ourselves as the first entry in the list, and that's that. If there are already entries in the list, then we need to dig a little deeper.
Next, we check to see if we're already at the end of the list. If we are, we probably shouldn't add ourselves again. It would be bad for the same page to be listed more than once to the user!
Now that we've determined we're not the last entry in the list, we need to do something really tricky. We'll search the list to see if we're in there. Let's assume that we're already in the list at some point. If the user wants to go there, we shouldn't show them the entries that follow, so we'll need to flush the rest of the list. It's of no use to us, so wave it goodbye! Now that the list ends with us, we don't need to add ourselves again, so we're done.
If we've found that there was nothing to flush (we weren't in the list), then we need to add ourselves to the end of the list. In doing so, we've completed our task of maintenance, and should allow the page to be displayed.
Customization of HISTMAINT.INC, unless you want to radically change how the
list operates, there is very little to do. The only thing that would be a
common change is to include additional items for each entry. Why don't we use
the example we discussed earlier; that of adding an image URL. We would need
to change the number of items for each entry in the list. This is changed on
the ItemCount constant line:
Private Const ItemCount = 2
The two here is indicative of HistURL and HistText. If we wanted to add
HistImageURL, we would change this number to three. Also, we need to store
this new item for the entry. You will find two places where this is done.
These are when we are adding an entry to the end of the list, and when we are
filling the first entry of an empty list. The code for doing that looks
something like this:
HistPtr = HistPtr + 1
Session("HistLog").Add CStr(HistPtr), ThisImageURL
Both places use the same code, so there is no confusion as to which is which.
As far as basic customization of HISTMAINT.INC, that's all there is to be done.
Once again, with the exception of changing the basic operation of the list, there
are no other changes to be done here.
Well, sadly that's all there is to be said and done. Now it's time for you to go off and implement this tool on your own web sites. Happy Programming!
Attachments:
This ZIP contains the 2 include files, the GLOBAL.ASAsession setups, and 4 ASP pages that show how it's used. To run the example pages, you'll need to fix up the includes to point to the virtual path for the includes in each page, and place theGLOBAL.ASAin your application home path (usually the root of the web site.) If there is an existingGLOBAL.ASA, then it will need to be edited to add the constructors/destructors for the history dictionary and counter.
Bart Silverstein has written several great articles for 4GuysFromRolla.com. When he is not writing articles, Bart is often found on the many ASP messageboards, answering questions.




