We want to provide a standardized site map across our SharePoint publishing enterprise. We are using SharePoint to provide a content management solution for our partners, and migrating from Microsoft Content Management Server 2002. Part of the planning is defining the set of web parts that we will enable for our partners to use in creating their own sites and pages. Our partner count is in the hundreds at this point so we have a wide range of abilities to acommodate. Some of the users are web design and SharePoint gurus, and some of them have no HTML experience. It is for the latter that we need to be especially concious.
Our first attempt was to use the out-of-the-box TableOfContentsWebPart. This a useful part because of it’s customizability, but the same thing that makes it useful also makes it quite complex. It doesn’t provide a nice nested <ul> rendering out of the box, and we don’t expect a majority of our users to have SPD or any XSL expertise which are both needed to make this thing to what you want. So we sought to customize the part to render a nested <ul> tree with some custom XSL and then export the customized webpart to the gallery.
When I started on the XSL template I planned on using a recursive template because I had expected the XML coming from the TOC to be heirarchical (like the data it represents), something like:
<page title="a page" url="/pages/default.aspx"/>
Unfortunately, the XML is one level and uses a level attribute on the items (level="1", level="2") to be used for transforming. Not pretty, but it doesn’t matter right? I could still approach this with a fairly simple recursive XSL template. Afterwards, we had a perfectly good site map that could be exported and reused by anyone. Even more unfortunately though, the TableOfContentsWebPart has a limit on the number of levels it will emit in XML. The limit was 3. When the team came to me and said, "Hey we need this to show more than 3 levels," my first instinct was to think that there must be a good reason for limiting. Obviously you can’t let this thing run infitely deep, but why 3 levels? I surmised that 3 levels was probably enough to handle most sites and that if you have more than 3 levels of structure, using a site map wasn’t going to benefit a user. If at every level you have only 3 items, your tree starts getting big fast… level 4 has 81 items, level 5 has 243 items, level 6 has 729 items! Yeah that’s a good argument to not go past 3 levels. Performance aside, who is going to spend time reading through a lot of items in tree format to find a page or site? Isn’t that why we have an awesome search bar on every page? Well, usability and performance are not always of concern to our partners, some of which actually do have sites with structure up to 7 levels deep.
My solution was to write a simple web part using the PortalSiteMapDataSource. This object was meant to do exactly what we are trying to do and is also built for performance. Read Chris Richard’s blog entry, Increased performance for MOSS apps using the PortalSiteMapProvider, from the Microsoft Enterprise Content Management team. It will provide speedy access the the underlying navigation tree and will handle caching for me. As Chris says, the first call to this provider won’t be as fast as using the OM yourself, because it’s handling a lot of caching heavy lifting in the background, but it will improve the performance of your Site Map overall and provide for very little coding.
So a couple hours later and some frustrating SharePoint development, we have a standard site map web part in our gallery. All our users have to do is add the web part to a page and if they want to, write some custom CSS to style it out.