Sometimes doing the simplest things turns out to be unnecessary difficult. This is true with SharePoint development in particular. For example: have you ever tried creating a menu control based on a standard Site Map Provider which would render a nested unordered list (UL) and nothing else? I have, and finally have a solution that I’m happy about: a templates-based menu control.
SharePoint and menus
If you ever looked at the out-of-the-box available Master Pages provided with MOSS 2007 you know that they use the standard ASP.NET menu control to render the navigation. While it definitely does the job, have you ever looked at the rendered HTML?
Compare how much markup is being used for a couple of menu items which could be rendered like:
<ul> <li><a href="/PressReleases/Pages/default.aspx">Press Releases</a></li> <li><a href="/Search">Search</a></li> </ul>
See the difference? A couple of issues should become clearly visible at this point.
ASP.NET menus are poorly accessible
Have you ever took a look at HTML as seen by screen readers or search bots? Because the links are buried under a bunch of tables it’s difficult for such applications to read them correctly. All the tables around the links make the visitors of your site loose the track of what they are “looking” at and just navigate away from your site. Additionally many search bots can’t properly deal with too complex markup. Making the HTML of your pages too complex can result in lower rating of your content.
How much markup do I have to download?
The markup of a standard ASP.NET menu I have showed you in the image above is 1308 bytes. Rendering the same menu using an unordered list is 185 bytes only! The standard ASP.NET menu produces 7 times more markup than you would want it to. Also consider the fact that the menu above consists of only two items. What if we were talking about a medium size website with 20 links? How much markup would you have to download only to see a couple of links?
Branding costs way too much time
ASP.NET menu anatomy
ASP.NET menus are not that bad. There are situations when you could use them and experience no problems at all. There are still many applications being developed for environments where performance, bandwidth and accessibility are not an issue. And although I would totally agree that it’s a bad practice to deliver poor markup, people do it, and it works.
ASP.NET menus have one great concept implemented in them: the templates. Using a template you can define placeholder for your data which is then filled using data binding. Although this concept could theoretically give you full control of the rendered HTML markup and separate the logic of the menu control from the rendered HTML, the ASP.NET menu fails to do the job correctly. Yes: you can define your own template but on the output everything you defined is still being rendered in a cells of a nested table.
We should know better
By know many people found their way around the issue of ASP.NET menus on MOSS 2007 Web Content Management solutions. So have I. In the last few years I have worked on a few Web Content Management solutions built on top of MOSS 2007: all of them being Internet-facing sites. In all that time me and my colleagues were trying to find a way to get rid of all these tables and get some more control over the rendered HTML to make it match the branding we had to implement.
At some point we stumbled upon the CSS-friendly Control Adapters. And while they definitely do the job I wasn’t particularly happy about writing HTML using .NET code. Mixing the logic of the Menu with a Control Adapter and the HTML rendering didn’t make it easier for us to maintain and modify the code when needed. Somehow it wasn’t the grail we were looking for.
In the meantime we tried some other approaches including inheriting from the standard ASP.NET menu controls, overriding stuff and creating our own controls from scratch. After all how difficult it can be to create a menu control that gets the data from a Site Map Provider and renders them as an unordered list? My answer? Much more difficult than it should be.
A solution (candidate)
Recently I decided to give it another chance. I still wanted to get the minimal amount of custom code, full control of the rendered HTML and preferably not use .NET to write HTML. I was still charmed by the idea of having these templates you could define in your Master Page/Page Layout.
Here are the results of my work:
Doesn’t look that awesome, does it? Now let’s have a look at the rendered HTML:
And this is how it did it:
To keep a long story short: I have developed a custom control that allows you to define custom templates and using data binding renders the menu items using your own templates!
Using the TemplatedMenu you can add a menu control to your page and use your own rendering without writing a line of code! Comparing to using a Control Adapter, the deployment of the TemplatedMenu is fully supported using the standard SharePoint WSP. If you want to use a Control Adapter in your solution, you have to deploy not only the assembly but also the .browser file what gets challenging in environments with multiple web front ends.
The TemplatedMenu is available on CodePlex. Feel free to experiment with it. I’m curious to hear if it works for you and if there is anything else you find challenging.
To help you understand what I’ve built and how it works I’ve included XML comments in the code. If you’re using DevExpress you can easily view it using the Documentor plugin.
The TemplatedMenu is provided as-is. Although it would be really cool if it could help you in your solution, I give you no guarantee it will. You use it at your own risk.
Download: Imtech SharePoint TemplatedMenu (ZIP, 12KB)
Technorati Tags: SharePoint,SharePoint 2007,MOSS 2007