Monday, March 12, 2007

Valid XHTML - the blogger navigation bar

pencil icon, that"s clickable to start editing the post

After having used blogger.com for some time i wrote a post on XPointer and tried some of the syntax out in Firefox I discovered that the markup blogger.com produces is NOT valid XHTML, for a number of reasons. This post will dive into the navigation bar

The navigation bar is not part of the template but is inserted serverside. When i started validating the navigationbar (navbar) gave some of the errors. I don'y not mind the navigation bar since it's sort of fair that the blogger.com brand is on the page and it has some practical links - I just wanted it be valid XHTML 1.0, and frankly I was very surprised that it wasn't, since it's quite easy to fix and affects all blogs, and not the least the rumor has it that the search engine Google loves wellformed and maybe also valid documents ;-).

With a standard template I got this right after the <body> tag (my formatting):

<div
  class='navbar section'
  id='navbar'>
  <div
    class='widget Navbar'
    id='Navbar1'>
    <iframe
      src="http://www2.blogger.com/navbar.g?targetBlogID=591744930960839717&amp;blogName=Sweetxml&amp;publishMode=PUBLISH_MODE_HOSTED&amp;navbarType=BLUE&amp;layoutType=LAYOUTS&amp;homepageUrl=http%3A%2F%2Fblog.sweetxml.org%2Findex.html&amp;searchRoot=http%3A%2F%2Fblog.sweetxml.org%2Fsearch"
      height="30px"
      width="100%"
      marginwidth="0"
      marginheight="0"
      scrolling="no"
      id="navbar-iframe"
      frameborder="0">
    </iframe>
    <div id="space-for-ie"></div>
  </div>
</div>

The URL (http://www2.blogger.com/navbar.g) has the following paramters:

targetBlogID=591744930960839717
So each blog has it own identifier and mine is 591744930960839717
blogName=Sweetxml
The name of my blog is Sweetxml, but I don't see why it's needed as a paramter in the URL since it should be trivial to lookup based on the targetBlogID.
publishMode=PUBLISH_MODE_HOSTED
Don't knwo what this means but probably it beacause I use the online editor and not FTP?
navbarType=BLUE
The background color I think, haven't had time to experiment with it.
layoutType=LAYOUTS
Don't now what it means or if it's really needed.
homepageUrl=http%3A%2F%2Fblog.sweetxml.org%2Findex.html
The index page for my blog
searchRoot=http%3A%2F%2Fblog.sweetxml.org%2Fsearch
the root URL used when searching via Google

It gave me 9 errors:

Error  Line 409 column 100: there is no attribute "src".
Error  Line 409 column 390: there is no attribute "height".
Error  Line 409 column 403: there is no attribute "width".
Error  Line 409 column 422: there is no attribute "marginwidth".
Error  Line 409 column 439: there is no attribute "marginheight".
Error  Line 409 column 453: there is no attribute "scrolling".
Error  Line 409 column 461: there is no attribute "id".
Error  Line 409 column 489: there is no attribute "frameborder".
Error  Line 409 column 492: element "iframe" undefined.

And the last one does explain some - the iframe is not part of XHTML 1.0 Strict, that is iframe is not part of HTML 4.01 Strict which is the recommended version, as written in the DTD:

This is HTML 4.01 Strict DTD, which excludes the presentation attributes and elements that W3C expects to phase out as support for style sheets matures. Authors should use the Strict DTD when possible, but may use the Transitional DTD when support for presentation attribute and elements is required.

An alternative and valid XHTML implementation would be:

<div class='navbar section' id='navbar'>
   <div class='widget Navbar' id='Navbar1'>
      <object type="text/html"
          style="height: 30px; width: 100%; margin: 0px; overflow: hidden;"
          data="http://www2.blogger.com/navbar.g?targ......g%2Fsearch"
          id="navbar-iframe">
         Your browser could show this page as an object, click on this link to see the<a href="http://www2.blogger.com/navbar.g?t...h">navigationbar</a>.
      </object>
      <div id="space-for-ie"/>
   </div>
</div>

Now how do I replace the invalid version with the valid one? Since I can't change anything on ther serverside direct, it will have to be through the template. I did some googling, and ofcourse others have tried the same, one of the hits were from the forum. Most of the hits showed how to hide the navbar through css and with some considerations as to wheter is was okay or against the rules. As for the rules it's not clear since if yuo post though FTP it doesn't have to be there, as it say's on one of the help page about the navbar Unless you publish your blog via FTP, the Navbar cannot be disabled, not that i understand why.

It clear from the markup and the hacks that the navbar is inserted right after the body tag, and the ugly and invalid noembed tag was no acceptable for me, so I tried different things until i found a clean hack, that's inserted before the body tag in the template:

<script type="text/javascript">
<![CDATA[
<!--
/*<body>*/
function dummy () {
}
-->
]]>
</script>

I've probably gone overboard in the three levels of comments but that doesn't hurt. When updating the template if actually discovers that the template is about to be hidden (though I havent' figured out how it can be that clever), here a screendump:

here's what the pages ends containing:

<script type='text/javascript'>
<![CDATA[
<!--
/*<body>
  <b:section id="navbar" class="navbar" maxwidgets="1" showaddelement="no">
    <b:widget type="Navbar" id="Navbar1" locked="yes"/>
  </b:section>

*/
function dummy () {
}
-->
]]>
</script>

So the navbar is inserted as a template in part of a two step process.

The navigation bar markup

This makes a valid reference to the navbar but what about the markup in the navbar itself. I can't really understand why it's implemented as an iframe that reference another (X)HTML document since in my view it could easily have been implemented right in the page, instead of dereferencing i through an iframe, but there must be some architectural idea to it or maybe just an architecture decision at some point :-). Maybe I'll have a look at the actual markup in another posting.