Using the PortalSiteMapProvider

I recently had a customer who wanted a simple web part that just listed the subsites of a site – something like what you see in SharePoint’s “View All Site Content” page, but for a couple of levels, rather than just one. Obviously, this would be quite simple to do directly by traversing the SPWeb object and it’s children, but it struck me that there must be a better, standard way – ideally one that uses a bit of caching or optimisation.

I found myself looking at the PortalSiteMapProvider for the first time. I’ve written my own NavigationProviders before now, and I’ve used some of the out of the box ones, but the PortalSiteMapProvider is an object I’ve never really used, or become familiar with. Here’s what I found…

I added a new Navigation Provider in my Web.Config. None of the standard, out of the box configurations were quite as I wanted:

<add name="AWBTestNav" description="" type="Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider, Microsoft.SharePoint.Publishing, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" NavigationType="Current" EncodeOutput="true" IncludePages="Never" IncludeSubSites="Always" IncludeHeadings="false" IncludeAuthoredLinks="false" />;

This navigation provider, for the current site, never shows pages, headings or authored links, and always shows subsites.

Then I added a new SiteMapDataSource and Menu to my page:

<asp:SiteMapDataSource SiteMapProvider="AWBTestNav" ShowStartingNode="false" id="AWBTestSiteMap" runat="server"/>

<SharePoint:AspMenu id="AWBNavMenu" DataSourceId="AWBTestSiteMap" runat="server" Orientation="Vertical" StaticDisplayLevels="2" ItemWrap="true" MaximumDynamicDisplayLevels="0" StaticSubMenuIndent="0" SkipLinkText="" >
... (Left out the Level styles) ...

You’ll notice that we’ve got 2 levels being displayed in the menu. And Presto:

Picture of Web Only Menu output

Of course, we could interact with the provider directly. I wrote some code to traverse a few levels:

PortalSiteMapProvider psmp = PortalSiteMapProvider.WebSiteMapProvider ;
SiteMapNode rootNode = psmp.CurrentNode;
// output the node here
PortalSiteMapNode psmn = rootNode as PortalSiteMapNode;
SiteMapNodeCollection nodes = psmp.GetChildNodes(psmn, NodeTypes.Area, NodeTypes.Area, NodeOrder.LastModifiedDate, false);
foreach (SiteMapNode n in nodes)
    Recurse(psmp, n, 1);

private void Recurse(PortalSiteMapProvider psmp, SiteMapNode node, int level)
    PortalSiteMapNode psmn = node as PortalSiteMapNode;
    // output the node here
    // Arbitrary limit of 2 levels below root.
    if (level &lt; 3)
        SiteMapNodeCollection nodes = psmp.GetChildNodes(psmn, NodeTypes.Area, NodeTypes.Area,NodeOrder.LastModifiedDate,false);
        foreach (SiteMapNode n in nodes)
            Recurse(psmp, n, level+1);

This code gets me the root node, and 2 levels of subnodes, via the object model. And it does it with sorting and caching, which is neat.

Using the PortalSiteMapProvider

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.