Using a Text 'Content Linking' File

Where menu or links pages are concerned, maintaining your Web site is a real chore. A common solution if you have pages that act as a menu, containing several links to other pages, is to build the page dynamically from a database. We'll look at this topic later in the chapter. However, there are other less resource-intensive ways to do it. One of the best solutions, and one that never really gets the recognition it deserves, is the ASP Content Linking component. This is a surprisingly powerful tool for situations where you require a menu page, and where you have a series of pages that are viewed in series to form a complete topic.

What is Content Linking?

The Content Linking component uses a content linking text file that contains the relative URLs of each page, and the text to display as the hyperlink for that page. The clever part is that, once you instantiate the component on a page and tell it where to find the content linking text file, it knows where the current page is within the list. This makes it easy to provide links to the previous or next page, or directly to any other page in the list.

If you need to insert another page into the list, or change the order they are displayed in, you just edit the content linking text file. The links in each page are automatically updated. We use the content linking component mainly to save effort when creating sample file menus on the Web-Developer site, but we'll show you several other ways it can be used here.

Easy To Maintain Menu or Contents Pages

Each book on the Web-Developer site has a menu page showing all the samples that can be run from our site. As we build each set of samples, both during development of the book and afterwards as changes to operating systems and client software make updates inevitable, we need to add, remove and reorder the links. The content linking component makes this easy.

As an example, this is the content linking text file (contlink.txt) included with the code samples from this book. Together with the Content Linking component, it creates a simple 'contents' page of all our books, similar to the one on our Web site. In the file, the URL and text for the hyperlink are separated by a Tab character. An optional comment, which the component ignores, can be added after the hyperlink text and is again separated by a Tab character:

book1460.asp   Professional MTS and MSMQ Programming   comments can
book1266.asp   Professional ASP 2.0 Programming        be added here
book1568.asp   Instant HTML 4.0 Reference              if required
book0707.asp   Professional IE4 Programming
book0685.asp   Instant IE4 Dynamic HTML Reference
book0464.asp   Instant ActiveX Database Programming
book0448.asp   Instant VBScript Programming

Note that the URL can be virtual or physical, and is assumed to be relative to the content linking file page. If you want to be able to use the GetPreviousxxx or GetNextxxx methods, you can't use absolute URLs that start with http:, //, or \\

In the ASP code that creates the 'contents' page, we initialize the component and then call its methods to get the entries from the text file one at a time, in order, and insert them into the page. This is the working part of the page—we've removed the style section and the page heading to make it easier to see the actual ASP code:

<%@ LANGUAGE="VBSCRIPT" %>
...
<H3>Contents list:</H3>
<UL>
<% 
Set NextLink = Server.CreateObject("MSWC.NextLink")
intCount = NextLink.GetListCount("contlink.txt")
For intLoop = 1 To intCount %>
 <LI>
  <A HREF="<%= NextLink.GetNthURL("contlink.txt", intLoop) %>">
   <%= NextLink.GetNthDescription("contlink.txt", intLoop) %>  
  </A>
 </LI>
<% Next %>  
</UL>
...
</BODY>
</HTML> 
Here's the result—this is the content linking sample (content.asp) included with the code for this book:

Now, all we need to do to change the order of the links, the URL they point to, or the text of the hyperlink, is edit the content linking text file. And of course we aren't restricted to only using the component for text hyperlinks. It could equally well be used to provide captions for buttons, or even a set of text instructions that are not links at all, where the URLs are ignored.

Content Linking through Multiple Pages

However, rather than just providing a content page, we can use this technique to place automatically updated links into each page that the contents page refers to. The Content Linking component provides methods to get the index of the current page, or details of the next and previous pages in the list. We can even get details of any other page by providing its index in the list, as you've seen in the previous section of code.

So it's now easy to provide links to other pages. In each page we instantiate the component and call the appropriate methods. Each method requires the path of the content linking file, and in our example it's in the same folder as all the other pages. This is one of the pages in the list, with the important code highlighted:

<html>
<head>
<title>1568 Instant HTML 4.0 Reference</title>
<!-- #include file="bookstyle.inc" -->
</head>
<body BGCOLOR="#FFFFFF">
<!-- #include file="pagehead.inc" -->
<HR>
<h3><img SRC="/images/1568.gif" ALIGN="LEFT" HSPACE="10">
1568 - Instant HTML 4.0 Reference</h3>
The World Wide Web Consortium are finalizing the specifications ... etc.
<BR CLEAR="ALL"><HR>
<form action="">
<% Set objNextLink = Server.CreateObject("MSWC.NextLink")
strListFile = "contlink.txt"
intThisPage = objNextLink.GetListIndex(strListFile)
If (intThisPage > 1) Then %> 
  <input type="button" 
  onclick="location.href='<% = objNextLink.GetPreviousURL(strListFile) %>';"
  title="Previous Page" value="Previous">
<% End If %>
  <input type="button" onclick="location.href='content.asp';" 
  title="Contents Page" value="Contents">
<% If (intThisPage < objNextLink.GetListCount(strListFile)) Then %> 
  <input type="button" 
  onclick="location.href='<% = objNextLink.GetNextURL(strListFile) %>';"
  title="Next Page" value="&nbsp;&nbsp; Next &nbsp;&nbsp;">
<% End If %>  
</form>
</body>
</html>

The two #include lines near the top of the page are there to simplify design and maintenance. Instead of specifying the <STYLE> tag and the code to create the page heading each time, we placed them in separate include files, and we can than insert them into all the pages. Again, this makes it easier to update them, without having to edit each page.

The actual content linking code is the highlighted section. In this page, we're inserting three buttons that the viewer can use to go to the previous, next, or contents page. When we call the GetPreviousURL and GetNextURL methods to get the URLs of the previous and next pages, the component uses the string we specify to locate the content linking file and look up the URL of the current page. From that, it can extract the URL required.

You can also see the GetListIndex and GetListCount methods used here. These return the index of the current page within the file (starting at 1), and the total number of pages. We use these methods to make sure the previous and next buttons only appear if there are corresponding pages to go to.

Using Different Types of Links

As well as buttons, the content linking component allows us to use other kinds of links. If you run the sample we've provided (from http://webdev.wrox.co.uk/books/1797/), you'll see these as you move through the pages. For example, we've provided text links on one page, which display the description (the hyperlink text) of the next and previous pages:

This is easy, because the component provides the GetPreviousDescription and GetNextDescription methods, as well as GetPreviousURL and GetNextURL. Here's the code for the page shown above:

<UL>
<% Set objNextLink = Server.CreateObject("MSWC.NextLink")
strListFile = "contlink.txt"
intThisPage = objNextLink.GetListIndex(strListFile)
If intThisPage > 1 Then %> 
  <LI>Back to '<A HREF="<%= objNextLink.GetPreviousURL(strListFile) %>">
  <%= objNextLink.GetPreviousDescription(strListFile) %></A>'</LI>
<% End If %>
  <LI>Go to the <A HREF="content.asp">contents page</A></LI>
<% If intThisPage < objNextLink.GetListCount(strListFile) Then %> 
  <LI>Forward to '<A HREF="<%= objNextLink.GetNextURL(strListFile) %>">
  <%= objNextLink.GetNextDescription(strListFile) %></A>'</LI>
<% End If %>  
</UL>

We've also got a page that uses a loop to place a link to all the other pages, with the current page as just text and not a hyperlink:

In this case, we use the GetNthURL method to get the details and URL of all the pages in the list in turn. This method requires the index of the page we want as well as the path to the content linking file. For each page in the list, we write <A> tags around the page number to link it to the appropriate page, except for the current page where we omit the <A> tags:

<B>Go to page: &nbsp;
<% 
Set objNextLink = Server.CreateObject("MSWC.NextLink")
strListFile = "contlink.txt"
intThisPage = objNextLink.GetListIndex(strListFile)
intLastPage = objNextLink.GetListCount(strListFile)
For intLoop = 1 To intLastPage
  If intThisPage <> intLoop Then 
    Response.Write "<A HREF=" & Chr(34) _
      & objNextLink.GetNthURL(strListFile, intLoop) & Chr(34) & ">"
  End If
  Response.Write intLoop
  If intThisPage <> intLoop Then
    Response.Write "</A>"
  End If
  Response.Write " &nbsp;"
Next
%>  
<A HREF="content.asp">Contents</A> &nbsp;
</B>

The most ambitious example of links uses a button bar to provide navigation features. This is what it looks like in the page:

Because we use this in several of the pages, we created it as a separate file (buttonbar.inc) and we can then include it in each page as a SSI. Notice that the line that sets the value of the content linking file path variable is in the main part of the page. This allows us to use the button bar 'include' file in other places, with a different content linking file:

...
<% strListFile = "contlink.txt" %>
<!-- #include file="buttonbar.inc" -->
... 

Inside the buttonbar.inc file we create the component instance, get the current and last page indexes, and then calculate the index of the previous and next pages. The <FORM> section that follows the code contains the buttons, with the ONCLICK attribute of each set to a simple JavaScript expression that loads the appropriate page. These expressions are, of course, client-side script that will run on the browser when the user clicks a button:

<% 
Set objNextLink = Server.CreateObject ("MSWC.NextLink")
intListCount = objNextLink.GetListCount(strListFile)
intCurrentPage = objNextLink.GetListIndex(strListFile)
If intCurrentPage > 1 Then 
   intPrevPage = intCurrentPage - 1
Else  'cycle round to last page
   intPrevPage = intListCount
End If
If intCurrentPage < intListCount Then 
   intNextPage = intCurrentPage + 1
Else ' cycle round to first page
   intNextPage = 1
End If
%>

<form action="">
<input type="button" onclick=
 "location.href='<% = objNextLink.GetNthURL(strListFile, 1) %>';"
 title="First Page" value="&nbsp;|&lt;&nbsp;">
<input type="button" onclick=
 "location.href='<% =  objNextLink.GetNthURL(strListFile, intPrevPage) %>';"
 title="Previous Page" value="&nbsp;&lt;&nbsp;">
<input type="button" onclick=
 "location.href='content.asp';" 
 title="Contents Page" value="Contents">&nbsp;
<input type="button" onclick=
 "location.href='<% = objNextLink.GetNthURL(strListFile, intNextPage) %>';"
 title="Next Page" value="&nbsp;&gt;&nbsp;">
<input type="button" onclick=
 "location.href='<% = objNextLink.GetNthURL(strListFile, intListCount) %>';"
 title="Last Page" value="&nbsp;&gt;|&nbsp;">&nbsp;
</form>

Our 'button bar' code displays all the buttons all of the time, even if you are at one end of the list, and will cycle round to the other end of the list if clicked. You might like to implement it differently to hide the appropriate buttons instead.

Compatibility Issues

Pages containing buttons that use client-side scripting will, of course, only work on browsers that support client-side script. If in doubt, you can use text links in <A> tags for maximum compatibility. Also notice that we've included the buttons on a dummy <FORM> here, which has a blank ACTION attribute. Without it, Netscape Navigator will not display the buttons. We'll be looking at compatibility issues in more detail in the next chapter.

However, the end result—irrespective of the way we actually present the links—is a set of pages that the user can easily navigate through. At the same time, it's easy for the site administrator to add, remove and reorder them by editing the content linking text file. When the entries in the text file change, each page automatically reflects these changes the next time it is viewed.

For more details about the Content Linking component, look up 'Content Linking' in the Option Pack or your IIS documentation index. This provides a full description of the component, the content linking text file, and the methods that the component provides.

© 1998 by Wrox Press. All rights reserved.