Big Changes
Major XHTML Layout Rewrites
I moved the form tags that wrapped the entire page to specifically wrap the contact form. A friend of mine who codes beautifully, recommended this to me. So I'm going to give it a try. The tag is still in the master pages so it's easy to go back if I need to, but so far it works fine. In the month between when we finished the demo and initially developed this revision, we've been detoured getting a start on some serious C# programming. In fact, there are a number of things you can do outside the form tags using simple code render blocks or HTML controls that include runat="server" attributes. However, we finally uncovered some heavier programming areas where this does in fact collapse. Therefore, it's fortunate that the form elements were so easy to change because we needed to put them back. ASP.NET requires form tags be wrapped around some functionality we were trying to deploy, and while it will allow you to use more than one form element, but it only allows one form element with runat="server". Therefore, it's better practice to simply wrap the entire page in a form tag. Mine is nested just inside the <body> tag so it grabs everything. [chroniclemaster1, 2009/10/27] The page is also wrapped by the #outerContainer and #innerContainer divs, nested just inside the <form> tags. This is critical structure for the new Earth Chronicle layout, and I've incorporated some of the style rules for these divs into the Beta design. Most notably, using OO-CSS, I've added the style rules for padding on the #innerContainer div to create whitespace around the edge of the page.
Perhaps the most innovative change is the addition of several Shea extraDivs, empty div elements containing a nested span; extraDivs are used for applying additional background images to a design. Four Shea extraDivs sit at the very end of the #innerContainer tag. Another pair have been nested inside the main points div, though I'm not yet using any of them in the Beta layout. However, all four #innerContainer extraDivs are critical components in the Earth Chronicle design and had to be incorporated in the master pages. Looking ahead to the future, I expect to use these in the new Beta design, so the four Shea extraDivs at the bottom of the page are in the primary master page for all the sites.
The mess of divs in the footer have been reduced to a footer and it's wrapper; the cleaning was extremely thorough and dramatically improved the XHTML's semantics. The authorship section is renamed credits; the new #credits and the old #postingDates sections are each turned into a list. Each list item takes a unique class so I can target styling by credit or date. This is exactly what I've used to add alternating stripes as if this were a table design; I was very pleased with how well that worked out. Each list item contains an h4 element (for the title) and cite element (for the name / date). These more appropriate tags replaced a multitude of divs, each of which required special classes, because the div elements were not semantically specific of the purpose of the elements. These changes have made the #credits and #postingDates infinitely more readable in code, stripped out approximately half the previous markup, while giving similar if not improved flexibility.
The navigation is wrapped in new a pair of divs, #nav and #navWrapper, and the first element inside is a new skip link provided to satisfy guideline letter O of the section 508 accessibility guidelines. The three nav elements have been normalized. I've always thought this was taken care of, and yet I keep running across odd ways in which they're inconsistent. No more because I've upgraded each of the main nav elements and they're semantically consistent: the accessible page links and the top navbar (which have the same links), and the Earth Chronicle navbar at the bottom. Each is an unordered list in a wrapper div. Each list item has a nested list for the menu (in the accessible page links, the nested lists are the rows). The navbars are now driven by CSS only, so there is a conditional comment to call an IE6 javascript file. I wouldn't have written a script to drive the menus expressly for IE6. But since I already have one, I see no reason not to provide that important functionality to the many IE6 users. If you're not familiar with conditional comments, here's the second one I've included to pull in a special IE6 stylesheet.
<!--[if lte IE 6]>
<link rel="stylesheet" type="text/css" media="all" title="ecIeFixes" href="<%= ResolveClientUrl("../../CSS/2009/ecBetaIeFixesTesting.css") %>" />
<![endif]-->
A fundamental change in the design is how we approach CSS. Previously, I'd tested against IE6 first and then other browsers, working back and forth to find cross-browser compatible solutions by trial and error. IE7 and IE8 are sufficiently advanced in most areas that I was able to build a fully modern CSS2.1 design using cutting edge techniques in a completely standards compliant stylesheet. So this was my primary method of writing CSS unburdened from IE6. Then I incorporated a separate stylesheet for IE6 using Microsoft's preferred conditional comments to include it; it literally reads if "l"ess "t"han or "e"qual to IE 6, then include this XHTML. This means the main stylesheet is engineered more efficiently using all best practices and the very latest CSS techniques. Then the separate IE6 stylesheet is my shield against that browsers failings. This results in a more stable primary stylesheet and one that's much more powerful than anything I've ever done before. It's also more forward compatible in the sense that the IE6 stylesheet can be tossed when the browser is no longer important to support, and the main stylesheet will require no updating when that happens. Also note that the href attribute contains my new secret weapon. :)
The ResolveClientUrl() Method
This is the first inline expression - a block of code contained in an XHTML page between <%= ... %> characters - I've used in Earth Chronicle. Using the ResolveClientUrl() method, I've been able to incorporate the CSS <link> tags into a contentplaceholder tag inside the head element of the nested master page. This is huge! When you use .NET tilde notation for application root relative references for the link elements, they won't respond to the runat="server" attribute. I had gotten around this by placing runat="server" in the <head> tag. Once you wrap a contentplaceholder around the link elements, however, they're effectively isolated; ASP.NET can't process the paths via the runat="server" attribute in the head tag. This is unfortunate because wrapping the links in a contentplaceholder allows you to use these default CSS calls on every page simply by doing nothing. And if a page needs custom CSS, you simply insert a content element which corresponds to the contentplaceholder; the default <link> tags are thrown out and only what you specify in the content page will be used. The result is that I could not apply custom stylesheets to individual pages, when it seems like it "ought" to be simple to override the default stylesheet calls.
I've lived with this, but it seriously annoyed me. I put out numerous queries about this behavior on several expert boards every since I was first testing master pages, and I get a bee in my bonnet over it every few months and hit the boards again. Each time I got ideas but nothing that worked. When I was preparing for the "Medieval Scroll" demo, I really needed to insert custom CSS for the demo. In practice, I think it turned out to be a good thing, it made me build custom master pages for the design demo; that allowed much more flexibility and gave me the chance to experiment with the XHTML as well as the CSS, something I could not have done otherwise. Nevertheless, I heard back from someone at p2p.wrox.com about two days after I'd rebuilt the master pages for the design demo. They suggested yet another technique, but one I hadn't heard of before, a method called ResolveClientUrl(). Being up to my eyeballs in the design demo, I filed the idea away for future reference. Now that the demo is complete, I was incorporating a lot of the work I'd done back into the Beta website, I found that I had inadvertently tried to incorporate the links into the page inside a contentplaceholder. You'll understand why this was good design, but I'd forgotten the problem; predictably, my new pages could not locate the stylesheets. I considered just undoing everything, but remembering the post I'd set aside, I went back to research this technique. By calling this method inside an inline expression, I'm now able to perfectly incorporate CSS files in my master pages while allowing individual pages to override those calls if necessary. :D I also intend to work up a page about ResolveClientUrl() to better understand how it works.
However, I've already put it to a couple other uses. When using forward slash(/) application root relative references on my dev box, .NET demands that they begin /webroot/ECBeta/..., while my production server disagrees and demands /ECBeta/... causing problems anytime I shuffle files back and forth. Obviously, I use this technique as little as possible, but there are four places I use them. CSS and javascript files aren't processed by .NET; you can build them on the fly and do processing that way, but mine are not that sophisticated yet. I've sequestered those calls into one CSS file per website which I do have to change. The javascripts add optional functions, so I've built them using /ECBeta/... references that work fine on the server, but I have to add the /webroot reference to check it on the dev box which I rarely do; usually only during testing or when I first move it to the server.
The third location is the calls to add external javascripts in the primary master page. The <script> tag can't accept a runat="server" attribute because ASP.NET then believes it's a server side script. Therefore, I was having to remember to swap /webroot references whenever I swapped files between the dev box and production server. ResolveClientUrl() worked beautifully to remove this headache. The fourth and final location was a pair of src attributes in the user control for the Flash logo. As optional functionality, I'd set these to work on the production server, but I can't see them on my dev box (also IE never stops trying to load the bad file so it's always been annoying opening pages with Flash pages on my dev box with IE. By using ResolveClientUrl() to specify the paths to the .swf file, I can now call the Flash logo from the production server or my dev box using the same reference which no longer requires changes. So now only the CSS files still use /webroot references that I have to remove when I upload files.