|
|
||||||
|
|
![]() |
|
![]() |
|
||
|
|
||||||
Navigating Your Web Site with XML
One of the more common features of high-content sites these days seems to be the navigation bar found on the left-hand side of the screen. Usually placed in a table, this navigation bar is often a long laundry list of what's on the site. The problem with this approach is that you must hunt through the list to find what you're looking for. And because the navigation bar is contained within a table, it scrolls off the screen. If the list is long, you may find yourself scrolling back and forth to find what you're looking for.
In creating the plumbing for my site, www.Beyond HTML.com, I wanted to design a more structured approach to navigation using drop-down lists. The idea was to present a list of the Web site's main topics in the navigation bar. When you click on a topic, a list of subtopics or articles drops down, and clicking a second time on the topic folds, or closes, the drop-down list. I also wanted to use frames to present a consistent navigation bar that didn't scroll off the screen. Finally, I needed to provide an alternative table-based approach for older browsers that don't support frames.
My first attempt was to create a series of HTML files, each representing a different point in the navigation process. While this approach worked well, it resulted in a dozen or so navigation files. My problem was compounded by the desire to support both frames and tables. This meant that the number of files easily doubled since each file contained two implementations of the same menu. This would be a nightmare in terms of maintenance -- I'd need to rewrite the navigation bars every time I added something new to the site.
To work around this problem, I came up with a way to represent the physical layout of a Web site using XML. This XML representation then can be used to provide information to both the table- and frame-based versions of the navigation bar. As a bonus, this same representation also can be used to present both a site map and a complete table of contents to your visitors.
Designing the Vocabulary
There are two ways to represent a navigational structure. The first method is to view the tree from the document's perspective. This is the metacontent approach, where a self-describing document contains key information that can be used by the navigation bar. Each document can be scanned, and an XML structure then is generated from the document. The metacontent approach also can be used to represent a document's dependencies on other resources. This is a somewhat time-consuming process, and is probably better suited to site-management applications such as checking for broken links or missing resources.
The other approach is to examine the directory structure. In effect, this creates a site map that describes your site, and has a natural hierarchical structure, which is perfect for XML. The way it works is that you create an XML file that describes your navigational structure. Then a JavaScript function passes this description to the browser's XML parser as I described in "Parsing XML in IE4 with JScript" (see "Beyond HTML," Web Techniques, August 1998). The parser returns the structure with all of its elements exposed. Then you can use each element's attributes to construct the navigation bar. Ultimately, you can use another script to crawl your directory structure and automatically generate this XML file. However, for the purposes of this article I've created the XML file by hand.
The goal in designing the file's vocabulary was to keep it general. I used Microstar's Near & Far Designer to experiment with different content models. Near & Far is a structure editor, which is a visual tool that lets you quickly model document-type definitions (DTDs) by constructing a visual representation of the tree structure. In the end I resisted the urge to create specialized categories like Major Topic, Minor Topic, Article Entry, and so on. As you might imagine, any such specializations make the vocabulary application-specific. The idea is to reuse the content description in other applications, such as a site map, topic index, or table of contents. I might not have resisted this temptation had I used something other than Near & Far to experiment with the alternatives.
If you plan to use Near & Far, you may want to pick up a copy of Dave Megginson's Structuring XML Documents (see " Recommended Reading"). If you're developing DTDs, this book is a must-have. At the time he wrote it, Megginson was a senior architect for Microstar, so much of the notation used in the product is documented in this book.
The vocabulary employs a general object called
SiteNav, which contains the objects that describe the navigation entries. The only other object type isItemEntry. You describe all list entries using this single object. You can nest oneItemEntrywithin another to create subcategories and individual article entries. The syntax forSiteNavis shown in Example 1, and the XML document describing the navigation entries is given in Listing One. (All listings are available electronically; see "Source-Code Availability" on page 7.)Getting Framed
As I noted earlier, the most common approach to the navigation bar makes use of HTML tables. Virtually every site I've examined takes this road. My guess is that tables are easier to implement than frames, particularly for those high-end layout tools these sites often use. Some people may tell you that tables are better supported than frames in older browsers. And there are concerns that the commercial search engines won't be able to crawl frame-based sites. But there are drawbacks to using tables. The most cumbersome one is that tables are very slow. That's because the browser must examine every cell in the table before it can render any of its elements. In addition, there's no way to make common elements persistent. Thus, important elements such as your Web site's logo, copyright information, or those rotating banner ads and corporate sponsorships you're selling may scroll right off the screen.
Frames can solve many of these problems. But shortly after their introduction, frames got a bad rep, mainly because of rampant abuse by so-called designers. The fact is frames let you update portions of a screen, thus easing the bandwidth problem. They also let you make common elements persistent on the screen, so the browser doesn't have to redraw them as often. And despite what the spaghetti hacks may tell you, the 3.0 browsers support frames quite nicely, thank you!
Using frames, I've divided the screen of my site into three window panes: The navigation bar runs vertically down the left-hand side of the screen; a second pane to store banner ads or the site's logo is positioned across the top; and the remainder of the screen, the main window, is used to view content. The code for this arrangement is given in Listing Two. I won't bore you with a tutorial on frames: Raggett on HTML 4 by Dave Raggett et al. and Lincoln Stein's How to Set Up and Maintain a Web Site both provide excellent discussions (see "Recommended Reading"). However, note that I've turned off borders and disabled scrolling for all panes except the main window. Each frame is given a name that can be referenced from within the script. The navigation bar is called
NavPane, the top frame is calledTopPane, and the main window is calledMainPane. The HTML forTopPaneandMainPaneare maintained in separate files. The HTML for the navigation frame will be generated on the fly. The result is a functional design with an open look and feel.Of course, you should provide alternatives for the browsers and Web devices that don't support frames. You also should give the search engines something to look at. So I've taken advantage of the
<NOFRAMES>element to provide a table-based alternative. This alternative code supports frames-impaired browsers while providing an entry point to your site for the search engines.Processing the Structure
Listing Three contains the script to process the XML file and generate the navigation bar. The basic steps are to create a new XML document object and assign the XML file to this object using the document's
URLproperty. This code is contained in theParse()method. This method should look familiar -- it's similar to theParse()method described in the August column previously mentioned.Parse()assumes that you've instantiated the MSXML ActiveX control with a tag in your HTML code. Next, the preliminary HTML statements are sent to the browser window so that it can accurately display the list. Once you've taken care of these details, you can calldisplayNavbar(). ThedisplayNavbar()method then is called to generate the list, and the closing HTML statements are written to the window. You can find a more detailed discussion of theParse()method in the August column.The XML parser in Internet Explorer exposes a number of its properties and methods.
displayNavbar()uses these methods to read the XML file and to display the items in the navigation bar. After ensuring that a valid document object is passed, this routine checks to see how many items are in the list and assigns that value tolength(). The first object you're going to see isSiteNav, which is simply a container for the list of items. It's a good idea to verify that you have this object and provide suitable error handling if you don't. At the same time,SiteNavrequires no processing, but must nevertheless be traversed in order to get to the list items. Theif (docObject.tagName != "SITENAV")statement serves both purposes.Next,
getAttribute()is a simple method that takes the name of an element's attribute and returns its value.getAttribute()is used to get the valuesHREF,Title, andDescription, which are contained within anItemEntry. Once you have these attributes, you can write the hypertext link out to theNavPaneusing awriteln(). The tricky part is that double quotes and other special characters must be prefaced with a backslash (\). Otherwise, the JavaScript will interpret the double quote as the end of the string. The last step is to check to see if there are any more child elements in the tree and make a recursive call todisplayNavbar()if there are.Putting it Together
You should be able to drop Listing Three into an HTML file. In the frames example in Listing Two, I placed the code in the
TopPane. Wherever you place it, the HTML file will need to create an instance of MSXML, which is an ActiveX control. There are two ways you can do this in IE 4: either by callingnew ActiveXObject("msxml"), or by creating an HTML object using the<Object>tag as shown in Example 2. IE 5 provides another alternative, thedocument.load()method. I prefer using the<Object>tag since it's a more universal approach, making the code easier to port to other browsers.Old Business
I received a few letters regarding the XML parser code discussed in the August column. In all cases, readers were getting the script error shown in Example 3 from IE 4 browsers. At first I was perplexed, since the code was developed using Internet Explorer 4.72. I was even more perplexed when I discovered I was receiving the same error. I traced the problem to the
window.open()method, which was no longer working correctly in IE. With a quick posting to the newsgroups, I discovered that two conditions can cause this problem.First, it can occur when you install a program that doesn't properly register its interfaces in the registry. The offending registry key is HKEY_CLASSES_ROOT\Interface. A more obscure condition arises when you create a Web browser control using Visual Basic 5.0, then uninstall VB. Microsoft acknowledges the problems in a technical note (Article ID: Q180176). If you experience problems with the
window.open()method or the code from the August column, refer to this technical note (available in the Microsoft Knowledge base at www.microsoft.com) to resolve the problem. (Also see " Online")Closing Thoughts
I mentioned that one of my goals in creating the navigation bar was to produce menu items containing drop-down lists. It turns out that this a nontrivial problem: Because the navigation bar is generated on the fly and is in effect contained within a separate HTML document, there's no direct way to capture the current state of the menu. In addition, it's also difficult to pass events from one page to another. It turns out that there are several possible solutions including generating the menu processing code on the fly using scriptlets. But that will be the subject of another column.
(Get the source code for this article here.)
Michael is a freelance writer, and currently serves as Web Techniques' editor at large. Many of the techniques described here can be seen in action at www.BeyondHTML.com. He can be reached at mfloyd@lifestylesSantaCruz.com
|
|