Monday, July 19, 2010

Configuring the breadcrumb for pages in _layouts !

If you have ever added a page to the _layouts or _admin folders in SharePoint 2007 you may have wondered how to get the breadcrumb to appear at the top of the page. As with many things in MOSS they are using the standard ASP.Net 2.0 navigation features, in particular the sitemap.

To see how it’s done you can simply open the layouts.sitemap (or admin.sitemap) in the ‘_app_bin’ folder of a MOSS IIS site to see how the breadcrumb is built. By editing this file you can ensure your own pages have a breadcrumb and the navigation works.

Now, having done that the chances are that you are going to create a feature so that this page can be used on other sites or farms. Great, you can create a Solution Package and add a file to the LAYOUTS folder which has a specific naming convention – layouts.sitemap.???.xml – where ??? is the name of your feature (has to be unique). This will then get merged into layouts.sitemap when you create a new application.

This is where there appears to be a problem…existing sites will not get updated with your new entries. I have found no way of updating the existing layouts.sitemap (or admin.sitemap) for every server in a farm using the SharePoint API. This problem is compounded by the fact that the sitemap is copied when the IIS site is created and so each IIS site (zone) in a application has to be updated.  

Ideally you could update the layouts.sitemap when your feature gets activated on every server in the farm and for every IIS site within the site collection.

This is where the UpdateLayoutsSitemap class comes in. UpdateLayoutsSitemap gives this functionality by creating a SharePoint job which is executed by OWSTIMER. Updating the layouts.sitemap can be as easy as this…

public override void FeatureActivated(SPFeatureReceiverProperties properties)

{

    SPWeb oWeb = (SPWeb)properties.Feature.Parent;

 

    SPThings.UpdateLayoutsSitemap uls = new UpdateLayoutsSitemap(oWeb.Site.WebApplication);

    uls.AddEntry(“Our Settings”, “/_layouts/oursettings.aspx”, “/_layouts/settings.aspx”);

    uls.AddEntry(“Add New Thing”, “/_layouts/addnewthing.aspx”, “/_layouts/oursettings.aspx?List=1″, “List”);

    uls.SubmitJob();

}

This will cause two new entries to be added to the layouts.sitemap for the specified WebApplication. The second entry will be a child of the first. But wait, if you have gone to the trouble of creating your layouts.sitemap.???.xml file would it not be better to use that? Of course you can…just don’t forget to replace the ??? with your own unique name.

public override void FeatureActivated(SPFeatureReceiverProperties properties)

{

    SPWeb oWeb = (SPWeb)properties.Feature.Parent;

 

    SPThings.UpdateLayoutsSitemap uls = new UpdateLayoutsSitemap(oWeb.Site.WebApplication);

    uls.AddSitemap(“layouts.sitemap.???.xml”);

    uls.SubmitJob();

}

It should also be noted that you can update admin.sitemap as well by adding true to the constructor…

SPThings.UpdateLayoutsSitemap uls = new UpdateLayoutsSitemap(oWeb.Site.WebApplication, true);

UpdateLayoutsSitemap inherits from SPJobDefinition and works by keeping track of the entries and adding them on every server that executes the job. SPJobDefinition is a very helpful class in that it inherits from SPAutoSerializingObject and so can persist all the class members you specify when the job is submitted. This means that when your job executes it is in the same state as when it was submitted. To enable this functionality you need to add an attribute to your class members so that they are persisted

[Persisted]

private System.Collections.Generic.List<string[]> _entries;

If you find it useful feel free to use this class as you see fit.

 

Download UpdateLayoutsSitemap Class File

No comments:

Post a Comment