Adding Breadcrumb Navigation to SharePoint Application Pages, the Easy Way

UPDATE: If you want to add breadcrumbs to pages provisioned in the SharePoint Central Administration site, read the follow post: http://weblogs.asp.net/jan/archive/2008/10/10/adding-breadcrumb-navigation-to-application-pages-in-sharepoint-central-administration.aspx

A while ago I posted an article about how you could build custom Application Pages for SharePoint that display the breadcrumb navigation, just like all the out-of-the-box Application Pages do. The trick was to add add a siteMapNode element in the layouts.sitemap located in the _app_bin folder of the SharePoint site. It's no problem to do this manually; just open the file in Notepad/Visual Studio add the siteMapNode in the desired parent node (e.g. Site Settings) and you're done. But in a production environment (especially with multiple front end web servers in the farm) you don't want to do this manually! Of course this can be done from a Feature handler; open the layouts.sitemap XML file in an XMLDocument, add the siteMapNode element and save it again. It sounds easy, but it gets complex again when you have multiple front end web servers; the code to change the layouts.sitemap should be updated on all those servers. A solution for this problem is to create a job definition that executes a job on all the servers. An example of this approach can be found over here.

The scenario described above is still quite complex; but a reader of my blog discovered that SharePoint actually has a built-in mechanism which is much easier to implement! First of all you need to create a file with a name formatted like layouts.sitemap.*.xml (the * can be anything), e.g. layouts.sitemap.demoapppages.xml. This file should be copied to the C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS folder. In this file you can put siteMapNode elements that should be added to the layouts.sitemap file, for example:

<?xml version="1.0" encoding="utf-8"?>
<siteMap>
    <siteMapNode url="/_layouts/demopage.aspx"
    parentUrl="/_layouts/settings.aspx" title="Demo App Page"/>
</siteMap>

The parentUrl attribute determines where the siteMapNode will be added in the hierarchy of the original layouts.sitemap file (in this case beneath the Site Settings page). SharePoint will merge the contents of layouts.sitemap.demoapppages.xml when a new Web Application is created (thus the layouts.sitemap file is created in the _app_bin folder). To force the layouts.sitemap file to be recreated for the existing Web Applications as well, you can use the copyappbincontent operation of the STSADM tool:

STSADM -o copyappbincontent

Or you can use the ApplyApplicationContentToLocalServer method of the SPWebService class (typically in a Feature Receiver):

public class FeatureHandler : SPFeatureReceiver
{
    public override void FeatureActivated(SPFeatureReceiverProperties properties)
    {
       SPFarm.Local.Services.GetValue<SPWebService>().
                    ApplyApplicationContentToLocalServer();
    }

    public override void FeatureDeactivating(SPFeatureReceiverProperties properties) {}

    public override void FeatureInstalled(SPFeatureReceiverProperties properties) {}

    public override void FeatureUninstalling(SPFeatureReceiverProperties properties) {}
}

I've created a small sample project on MSDN Code Gallery to show everything in action, that has the following components:

  • Custom Application Page (demopage.aspx), deployed to the _layouts folder
  • Custom SiteMap (layouts.sitemap.demoapppages.xml)
  • Feature, scoped to the web application level, that adds a link to the custom application page in the Site Settings page
  • Feature event handler to trigger the merging of all the sitemap files

So thanks Brian Staton for sharing your tip!

6 Comments

  • Dang.. that's smarts!

  • We took a similar approach when building TweakSP (www.tweaksp.com). Check out the DeploymentUtilities in the TweakSP.Deployment project as well as the AdminFeatureReceiver for another example.

  • When deactivating, do you need to call ApplyApplicationContentToLocalServer() again?

    Although, I'm not sure if the layouts.sitemap.*.xml would be removed before the FeatureDeativating method is run. Perhaps Feature Uninstalling would be better...

  • Hello,I met some problems when using your smartpart to add ajax user control.I have installed WSS SP1、MOSS SP1、ASP.NET Ajax Extensions,and I have configed the web.config file.But my ajax user control can't show normally.For example,when I push the button as you show in the demo video,it didn't work,means that it just do nothing.Sincerely need your help!Thanks!
    sink@live.cn
    (China)

  • @Paul: yes, the file needs to be removed, so the uninstall even should be ok.

    @sinkfish: please post your question in the SmartPart forums.

  • Weird, the stsadm command has the desired effect, but somehow the line of code in FeatureActivated has no effect. The line is executed though, I have traced through it.

    STSADM -o copyappbincontent

    and

    SPFarm.Local.Services.GetValue().
    ApplyApplicationContentToLocalServer();

Comments have been disabled for this content.