Tuesday, August 26, 2008

Create a Multi-Level SiteMapProvider

OK. Out of the Box, MOSS 2007 gives us this nice navigation interface. This is a publishing feature, so if you don't see it, you will need to activate it. We are able to create top level sites that give us two layers of navigation. So, the question is....

How do we get a multi-level navigation in MOSS? You need to write a custom SiteMapProvider. And here is how you do it ...

using System;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Navigation;
using Microsoft.SharePoint.Publishing;
using Microsoft.SharePoint.Publishing.Navigation;
using Microsoft.Office.Server;
using Microsoft.Office.Server.UserProfiles;

namespace ShannonBray.MOSS.MenuProvider
{
class MenuProvider : SiteMapProvider
{
PortalSiteMapProvider global;

public override SiteMapNode FindSiteMapNode(string rawUrl)
{
return global.FindSiteMapNode(rawUrl);
}

public override SiteMapNodeCollection GetChildNodes(SiteMapNode node)
{
return global.GetChildNodes(node);
}

public override SiteMapNode GetParentNode(SiteMapNode node)
{
return global.GetParentNode(node);
}

protected override SiteMapNode GetRootNodeCore()
{

// get the navigation elements of the current site
global = PortalSiteMapProvider.GlobalNavSiteMapProvider;

// use the settings that are configured on the 'Navigation' screen
global.IncludeAuthoredLinks = true;
global.IncludeHeadings = true;
global.IncludePages = PortalSiteMapProvider.IncludeOption.PerWeb;
global.IncludeSubSites = PortalSiteMapProvider.IncludeOption.PerWeb;

SiteMapNode menuNode;

PortalSiteMapNode currentNode = (PortalSiteMapNode)global.CurrentNode;

// continue to drill down if 'Inherit Navigation' from parent is set
// if not, return the currentNode of global

if (currentNode.WebNode.InheritNavigation == true)
{
SiteMapNode startNode = global.CurrentNode;
PortalSiteMapNode loopNode = (PortalSiteMapNode)startNode.ParentNode;

while (loopNode.WebNode.InheritNavigation == true && loopNode.ParentNode != null)
{
loopNode = (PortalSiteMapNode)loopNode.ParentNode;
}


menuNode = loopNode;

}
else
{
menuNode = global.CurrentNode;

}


return menuNode;


}

public override SiteMapNode CurrentNode
{
get
{
return base.CurrentNode;
}
}

public override SiteMapNode RootNode
{
get
{
return base.RootNode;
}
}


}
}

1 comments:

Anonymous said...

Where do we put this code?