Click to return to the Web Content Management home page    
Web Workshop  |  Web Content Management

A Tale of Two Web Teams: Touring the Redesign Code


Robert Carter
Matt Oshry
George Young
Microsoft Corporation

August 25, 1998

The following article was originally published in Site Builder Network Magazine.

Introduction

This set of articles is part of a larger series describing the processes, features, functions, and implementation of the Site Builder Network's latest redesign, which went live in June. Compared to previous redesigns, this last iteration improved on many of the processes we subject ourselves to. This set of articles is about the code we developed.

Code development was complicated. In many instances, so was the code itself. As a result, what was supposed to be one article grew to four separate mini-articles. We developed some noteworthy functions -- and some hacks of which we're not particularly proud. We include descriptions of both.

Be advised that these articles are not for the squeamish. We will do what we can to provide cogent descriptions, but if reading about nested arrays using conditional loops isn't your cup of tea, then you're out of luck. If you've read Robert Carter's overview article Building a Better Workshop, you know that we needed to pursue many agendas simultaneously, not all of which were complementary. For example, we were absorbing into our site the former Internet Client SDK (InetSDK), which used a different publishing process. Also, in a questionable nod to those of you who use either SBN or the InetSDK offline (through our CD-ROM releases, for example), we were saddled with some design decisions that made for ugly code. We'll discuss those decisions and processes wherever they impinged on the code, either pro or con.

This introductory article focuses on our goals for the redesign code. The second installment (Part 1) covers NavBar, the navigational aid we use througout SBN. The third article (Part 2) discusses NavFrame, a set of features that activate and control display of the SBN Table of Contents (TOC) frameset. The fourth article (Part 3), Other Special Features and Hacks, is a catch-all showcase of our proudest (and ugliest) moments.

A Few of Our Key Goals

In addition to some general design and usability guidelines for the new SBN Workshop (more fully discussed in Redesigning the Site: Planning and Managing, we had some criteria for our code. While we may not have been able to accomplish all of our goals for Release 1.0, they're still on our list as important modifications for future versions.

First, we wanted to maximize site performance. To do that, we have formatted our pages using linked CSS style sheets instead of HTML. In that way, we keep the HTML "clean", light, and structural. All our formatting information is kept within a few global files, which simplifies any updating we want to make. And while we incur an additional hit on the server to access and interpret a linked style sheet, that hit is paid back each time a user visits an additional article or page on the site (because the style sheet is cached, there's no need to download it again). We also wanted our code portable and manageable, so we used includes (conditional and otherwise) wherever possible.

In addition, you'll see a continuing effort by the SBN developer team to separate form from function and behavior whenever possible. If you look at any of the special new features we describe in this article, you'll see a complete separation of style, function, and content through the use of CLASS and ID tags. Classes are used primarily for style sheets. Where possible, we use the CLASS names to associate functionality with those elements as well. For example, in our NavBar code, all the items of CLASS="clsMenuTitleDown" display the same behaviors, so we can use the CLASS name to specify those elements in our code. If we can't associate functionality to a group of elements, we use the ID tag instead. If specific functionality is common across ID elements, we use a naming scheme that allows us to use string processing to identify the appropriate element. The NavBar menu naming scheme (IDMenu1, IDMenu2, IDMenu3 ...) illustrates this point.

Before we get to discussing the code in detail, a short and honest digression is in order. The publishing orientation of the SBN and InetSDK teams could not have been further apart. The SBN team is one of the leading proponents and practitioners of ASP in Microsoft, and as a result has a distinct slant toward performing work on the server. The InetSDK team, on the other hand, comes from a stalwartly client-side orientation. And yet the twain decided to meet. The result is here before you. Two of the authors of this article, George Young and Matt Oshry, were integral in structuring the merge (with Robert Carter looking over their shoulders, saying, "What's that for?") in a manner that would achieve a seamless appearance without imposing too great a production burden on our editorial staff. Both still want to implement some changes (targeted for Release 2.0), but they nonetheless gracefully consented to this (in their eyes premature) code exposé.

Will That Be Client- or Server-Side?

A recurring theme in our decisions was whether to process code on the client or the server. There are tradeoffs to each. In true compromise fashion, we presently do both. The first thing we do when somebody requests an SBN page is sniff for browser type. If a requested page comes from the SBN team, it will use ASP to sniff for browser type. If the browser can handle our NavBar code, we send that; otherwise, the browser will get our downlevel version. If the page comes from the InetSDK team, the downlevel version is sent by default. We then sniff for browser type on the client, and if the browser can handle NavBar, our sitewide navigational aid, we use outerHTML to replace the downlevel version.. The server-side approach to NavBar (viewable at the top of this page in a very tasteful blue), is detailed in Part 1: NavBar: Dynamic Menu Generation. We cover the InetSDK team's process for handling the same functionality in Part 3: Other Special Features and Hacks.

We browser-sniff for two reasons. One, we want to identify all users of Internet Explorer 4.0 and 5.0 browsers running on Windows and UNIX (they'll get all the snappy DHTML menus and effects). Two, we assign different stylesheets for each version of Internet Explorer 4.0 and up, Internet Explorer for the Macintosh, Internet Explorer 3.0, and Netscape Navigator 4.0 users.

We use the HTTP UserAgent string to sniff, using the following snippet:

sAgent = Request.ServerVariables("HTTP_USER_AGENT")

(Note that, for portability and ease of update, the browser-sniffing code is inserted into the page using a server-side include. If a new browser comes out, or we want finer detail in the platforms we sniff, we have to update only one file, rather than perform a global seach-and-replace on every file in the site.)

<!--#include virtual="/sitebuilder/shared/uadetect.asp"-->

Here's the code itself, which includes sniffing for Internet Explorer 5 and Windows 98.

If Instr(sAgent, "MSIE") Then
  If Instr(sAgent, "MSIE 3.") Then
    bIsIE3 = True
  ElseIf Instr(sAgent, "MSIE 4.") Then
    bIsIE4 = True
  ElseIf Instr(sAgent, "MSIE 5.") Then
    bIsIE5 = True
  End If
End If
   
If bIsIE4 And Not(InStr(sAgent,"b1") > 0 
  Or InStr(sAgent,"p1") > 0 
  Or InStr(sAgent,"p2") > 0) Then
    bIsIE4Final = True
End If
   

bIsWin32 = InStr(sAgent,"Windows 95")  > 0 
  Or InStr(sAgent,"Windows 98") > 0 
  Or InStr(sAgent,"Windows NT") > 0 
  Or InStr(sAgent,"Win32") > 0
   
If (bIsWin32) And (bIsIE3 Or bIsIE4 Or bIsIE5) Then
  bDoesActiveX = True
End If

Once we've established what browser a visitor has, we selectively send code and HTML using server-side includes.

Some Thoughts for Release 2.0

Obviously, the first thing we have to do is synch up our code processes better. For example, as much as we crow about using includes for portability, we still manage to store the same functions in several different files. To make matters worse, each instance of the functions is accessed by different files. Job 1, then, is to compile a master list of the locations each function resides (or each set of functions, since functions that call each other tend to be bunched together), and rationalize them to one, and only one, location. Where it makes sense, we'll combine interdependent functions into one file (all the NavFrame functions, for example), and ensure that both the SDK and SBN teams access them in the same fashion.

Another goal is to improve our downlevel version. Right now, the DHTML menus and all the snappy functions associated with our uplevel version combine to minimize the amount of clicking and navigating necessary find a desired article. The downlevel version is a lot less smooth. It takes three clicks to jump from a contents listing for one area to a contents listing for another. What's worse, the default pages for each section are populated with generic placeholder text, and most of the text is appropriate for Internet Explorer 4.0. Yikes!

Beyond damage control, we're also pursuing some funky new features. One of our coolest ideas for Release 2.0 should make our resident XML columnist, Charles Heinemann, blush with pride. You see, we plan to use XML to manage and generate our contents.htm files, the left-frame Tables of Contents (TOCs) for each Web Workshop area. The main reason we want to migrate to XML is to create a custom tag that allows the InetSDK team to version their products, synchronizing the InetSDK content with Internet Explorer releases. In so doing, we avoid having to maintain multiple versions of contents.htm, the bane of any self-respecting editor's existence. When successive versions of Internet Explorer are released, we can then update the code that controls which XML elements to display.

Once you decide to switch to XML, lots of other benefits accrue. A personal favorite is that you can use tag titles that have some bearing to what you're including. For example, this is our present contents.htm structure:

<LI CLASS="clsShowHide">
<A CLASS="clsTOCHeading">DHTML General Info</A>
<UL CLASS="clsItemsHide">
  <LI>
  <A CLASS="clsTOCItem" 
    HREF="/workshop/author/dhtml/dhtmlovw.asp">Overview</A>

Using XML, we can create a tag structure that looks something like this:

<SECTION CONTRIBUTOR="SBN">
   <SECTIONINFO>
      <TITLE>DHTML General Info</TITLE>
   </SECTIONINFO>

   <ARTICLES>
      <ARTICLE CONTRIBUTOR="SBN">
         <HREF>/workshop/author/dhtml/dhtmlovw.asp</HREF>
         <TITLE>Overview</TITLE>
      </ARTICLE>

A little more intuitive, wouldn't you say? We process the contents.xml file with a "master" XSL style sheet to generate the final contents.htm document that the browser displays. We can maintain separate "master" XSL style sheets for different output devices, user agents, and purposes, such as Internet Explorer on Windows CE or a TOC that lists only SDK documents. We'll also be able to do a bunch of other stuff. We'll tell you all about what we end up doing after we get it done. Stay tuned.

Summary

There you have it, or at least the beginning of it (we reserve the right to add a few more features later). You might have surmised by now, even if you haven't read the other three parts, that there's a lot of code doing a lot of things in the new design. Sometimes, different code performs the same work, but in different ways or at different times. We hope to eliminate any unnecessary redundancies for Release 2.0.

We're particularly proud of this version of Workshop, because we've provided not one, but two distinct navigational aids. NavBar can access every area of Site Builder Network, from the Magazine to the Workshop to Member Community; the drop-down menus allow you to go directly to every top-level area within the different parts of the site. Within Workshop, NavFrame allows you to navigate within each area, and down an additional two levels; even better, you can turn the left frame off to devote all your valuable screen real estate to any articles you're interested in.

In the course of combining NavBar and NavFrame, and assimilating the production process of the InetSDK team, we also developed some new programming constructs that could easily come in handy at your sites. Event caching is our term for capturing standard page events, such as onclick and mouseover; once captured, you can change what Internet Explorer does when those events are fired or where on the page they'll be recognized. DynaBinding, our other innovation, can work in conjunction with, or independent of, event caching. DynaBinding allows you to associate events or behaviors with elements on a page, even if you don't know whether those elements, or how many of them, will be on the page beforehand. As such, DynaBinding could be very helpful to those of you generating pages dynamically from databases.

In the interest of being complete, we've also shared with you some of our frustrations, and the hacks that resulted from them. The best example of a true hack is the aptly named hackURL(), our reconstruction of a URL with a query string that spurs Internet Explorer to redraw the frameset with a new TOC in the left frame.

It was a lot of work. It continues to be a lot of work. Hopefully, all our knees-bent-running-about has served its purpose: a more intuitive and faster Site Builder Network.



Back to topBack to top

Did you find this material useful? Gripes? Compliments? Suggestions for other articles? Write us!

© 1999 Microsoft Corporation. All rights reserved. Terms of use.