Mark Gilbert's Blog

Science and technology, served light and fluffy.

We do not follow Sitemaps to buried treasure (Part 1 of 2)

For several weeks now, I’ve been working on a MOSS project where we’re really pushing SharePoint Server to its limits in some areas, specifically branding.  Many weeks ago, when we were first putting together the new master pages (or more correctly, the first iteration of the master pages – we’ve revised them several times since then), we started realizing that the site we wanted to build had a much richer structure than what any of the built-in site map providers could generate for us.  There was a lot of cross linking going on, and multiple links to the same pages, and to be able to take advantage of the built-in site providers meant that we would have to have a REALLY convoluted site structure.

So, we opted to use a simple ASP.NET sitemap file, and build our navigation off of that.  That allowed us to keep the MOSS structure simple and logical, but still give us the flexibility to create the navigational structure we needed.  This decision came with a cost, though – the sitemap files would have to be manually maintained.  This cost seemed acceptable since the production site would only have a dozen pages added each year (at least, a dozen pages that would actually need links from the navigational menus).

The sitemap files themselves reside in the web root on the SharePoint server, and not in SharePoint-proper (aka, the content database).  For each web application that you create or extend in SharePoint, you get a new directory in C:\Inetpub\wwwroot\wss\VirtualDirectories.  Once you looking at a specific virtual directory, you’ll see the familiar folders associated with straight (e.g., non-MOSS) ASP.NET applications – bin, App_GlobalResources, etc..  The sitemap files have a very simple XML structure to them:

<?xml version=”1.0″ encoding=”utf-8″ ?>
<siteMap xmlns=”; >
      <siteMapNode title=”Menu” description=”Menu”>
            <siteMapNode title=”Leaf Node” description=”Leaf Node” url=”/LeafNode.aspx” />
            <siteMapNode title=”Submenu” description=”SubMenu”>
                  <siteMapNode title=”Leaf Node 2″ description=”Leaf Node 2″ url=”/LeafNode2.aspx”>

The structure of the menus follows the structure of the siteMapNode tags where child tags translate into submenus.  Once you have this in place, you need to add a provider element to the web.config:

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>
            <siteMap defaultProvider=”CurrentNavSiteMapProvider” enabled=”true”>
                        <add name=”MySiteMap”
                                  siteMapFile=”MyCustomMap.sitemap” />

All of the built-in providers have entries in the sitemap/providers area.  The key attributes for your tag are:

  • “Name” will be referenced later in the master page markup (see below), and this can be anything you’d like, so long as there isn’t another sitemap provider with the same value.
  • “Type” needs to be System.Web.XmlSiteMapProvider.
  • “siteMapFile” is the name of the file itself. The path here (I think) is relative to the web root on the file system, so theoretically you could put all of your sitemap files in a subfolder, and then use a path such as “subfolder/MyCustomMap.sitemap” here. I’ve never tried that, so it may not work, or work without jumping through a few more hoops.

Finally, in the master page, create an asp:SiteMapDataSource control that points to your new site map provider:

<asp:SiteMapDataSource runat=”server” id=”SiteMap1″ SiteMapProvider=”MySiteMap”/>

And then create an asp:Menu control that uses this as its data source:

<asp:Menu runat=”server” id=”MainMenu” DataSourceID=”SiteMap1″>

Now, the fun begins.

We had been working on our site internally and had been showing it to the stakeholders regularly, but always while it was running on our network.  The development had reached a point where we could let the client use the site directly.  To do that we needed to extend our original web application and create the external version of the site.

The complete details behind extending a web app are beyond the scope of this post (or even my area of expertise).  My purpose here is to provide enough details so that you can avoid the two issues we encountered when doing this.  Both of the issues that I will describe are specific to pages that use XML-sitemap files.

Extending a web application creates a new virtual directory.  This makes sense since the process of “extending” a SharePoint web app really means to create a second (or subsequent) IIS virtual site to point to the same SharePoint content database.  One major reason for doing this is to set up a new path to the site, and with it a new authentication mode.  In our case, we wanted to use Windows authentication internally, but allow our client to log in via Forms.  Additionally, we needed to turn on Anonymous access for the external users since less than 1% of the users on the site – the content authors – will actually need logins.  All content is publicly available for reading.

So we extended the site.  The vast majority of our site will work just fine because all of the content and structure is stored in the content database.  Our sitemap files, however, are not stored here – they are only the file system and as a result don’t get copied from the source IIS site.  So, our first issue is that we have to copy our sitemap files from one folder to another, and we have to replicate our web.config changes to match.

This isn’t a huge deal, but certainly one that could trip us up later if we’re not careful.  For example, if we’re making changes to the internal copy of the sitemap file, and we’re pointing our browser to the external copy, and beating our heads against the monitor for an hour trying to figure out why the changes aren’t being reflected.

Next week I’ll detail a much more involved issue – one that even after it was solved generated more questions than was answered.

April 23, 2007 Posted by | MOSS | Comments Off on We do not follow Sitemaps to buried treasure (Part 1 of 2)