Good site usability often means removing links from one page back to itself. In this article we will look at how to create an ASP.NET User Control which will act as a common header to a site. It will automatically know which page we are looking at, and it will remove links to the same page from itself.
Include files in classic ASP
<table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td> <a href="/default.aspx"><img src="/images/xefteri.gif" width="300" height="65" border="0" alt="HOME -- Xefteri-Articles for Web Developers"></a> </td> </tr> <tr> <td> <a href="/default.aspx">Home</a> | <a href="/articles/default.aspx">All Articles</a> | <a href="/contactus.aspx">Contact us</a> | <a href="/about.aspx">About us</a> </td> </tr> </table>
We could give this file an extension of ASP, INC or even HTM, and then call it from another page like so:
- Relative: <!–#include file=”../../includes/header.asp”–>
- Virtual: <!–#include virtual=”/includes/header.asp”–>
The result would be something like this:
There are however, some problems with include files:
- The IIS Server caches interpreted scripts to increase speed. There is no way though to cache include files on their own. Rather, the page that includes them is cached as a whole. An alternative is to use Server.Execute(filename), but that is not the default use, and it has problems of its own.
- Include files are placed in the page before execution occurs. Dynamically positioning include files is possible but requires work-arounds.
- Code in the include files can conflict with code on the page, namely variables, if all code is not encapsulated into subs and functions.
Let’s take the case of creating a smart common header for a site, like we described above. This is possible, but actually pretty hard to do with classic ASP includes. The steps needed to do this would be something like this:
- Get the current page
- Create a conditional statement that will run different pieces of code depending on the current page
- For each link in the header that we want to turn smart, we would have to check if it refers to the current location. If it is, then we simply do a Response.Write of the text with no link. If each link does not refer to the current location, then we would output the text wrapped in its link.
That’s too much repetition.
Include files with ASP.NET: enter User Controls
We can still use include files in ASP.NET in pretty much the same way as classic ASP if we want to. However, User Controls offer greater flexibility, reliability and speed. We’ll see this as we create a header User Control for this site.
I am very much in support of good usability on all sites I work on. One of the important elements of a good navigational usability, according to Jacob Nielsen’s column, is to not provide links on a page that link to themselves. This simply confuses the users, who might be clicking on a link and coming back to the same page without realizing it. This problem is made even worse by many sites, which implement style sheets that make visited links indistinguishable from non-visited ones. The user is doomed to try links over and over, only to come back to a page they have already visited.
We can turn the above HTML (include file) into a User Control very easily. Let’s look at the complete code needed. The file will now be saved as head.ascx.
<%@ Control Language="VB" EnableViewState="False" %> <script language="VB" runat="server"> Sub Page_Load() Try Dim Referer As String = Request.ServerVariables("SCRIPT_NAME") Select Case Referer Case "/default.aspx" aHome.Href = "" aImgHome.Href = "" Case "/articles/default.aspx" aAllArticles.Href = "" Case "/contactus.aspx" aContactUs.Href = "" Case "/about.aspx" aAboutUs.Href = "" End Select Catch End Try End Sub </script> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td> <a id=" aImgHome" runat="server" href="/default.aspx"><img src="/images/xefteri.gif" width="300" height="65" border="0" alt="HOME -- Xefteri-Articles for Web Developers"></a> </td> </tr> <tr> <td> <a id="aHome" runat="server" href="/default.aspx">Home</a> | <a id="aAllArticles" runat="server" href="/articles/default.aspx">All Articles</a> | <a id="aContactUs" runat="server" href="/contactus.aspx">Contact us</a> | <a id="aAboutUs" runat="server" href="/about.aspx">About us</a> </td> </tr> </table>
Let’s explain what is happening here. The Request.ServerVariables(“SCRIPT_NAME”) gets the virtual path of the current page. We store this in the string variable Referer. For example, the virtual path of this page is /articles/23dec2002/default.aspx.
We then perform a Select…Case condition and turn off the self-referencing links from the page. We can do this easily because we have given each <a href> in our HTML a unique ID and told it to run on the server. To turn off the link for the About us link for example, we code it as aAboutUs.Href = “”. Setting the Href property to an empty string, actually removes it.
Adding the User Control on any page
To add this smart header now to any page, we must first register it and then call it:
<%@ Page Language="VB" runat="server" %> <%@ Register TagPrefix="UserControl" TagName="Header" Src="/usercontrols/head.ascx" %> <html> <head> <title>Xefteri - Smart headers and footers using ASP.NET User Controls</title> </head> <body> <UserControl:Header runat="server" /> ... </body> </html>
We have seen how easy it is to create a User Control that acts as a header for our site. With it, we can make it smart enough to eliminate any self-referencing links and thus improve usability on our sites.