Recently, I had a task where I needed to create a custom navigation for the SharePoint site; which essentially would have a list of menu items but before all of them there would be a link denoting the top level site where the rest of the items live under.
In this case we can easily use PortalSiteMapProvider.CombinedNavSiteMapProvider but the problem is that this provider will nt return hidden nodes. If your site IA is simple and you have few root nodes and all of the are displayed – you don’t care much and you can enumerate through those nodes. If some of the nodes are hidden however, you can get a hold of them by recursively getting the parent node as shown below.
So, below we have a class which inherits from a WebControl and parses through the node giving away a top node as a link.
PortalSiteMapProvider provider = PortalSiteMapProvider.CombinedNavSiteMapProvider;
protected override void CreateChildControls() {
base.CreateChildControls();
SiteMapNode currentNode = GetTopNode(provider.CurrentNode); SiteMapNode rootNode = provider.RootNode; SiteMapNodeCollection nodes = rootNode.ChildNodes;
HtmlAnchor anchor = new HtmlAnchor();
foreach (SiteMapNode node in nodes)
{
if (currentNode.IsDescendantOf(node) || currentNode.Equals(node))
{
anchor.HRef = node.Url;
anchor.InnerText = HttpUtility.HtmlDecode(node.Title);
break;
}
}
if (string.IsNullOrEmpty(anchor.InnerText))
{
anchor.HRef = currentNode.Url;
anchor.InnerText = HttpUtility.HtmlDecode(currentNode.Title);
}
this.Controls.Add(anchor); }
private SiteMapNode GetTopNode(SiteMapNode currentNode)
{
if (currentNode.ParentNode.ParentNode!=null)
{
return GetTopNode(currentNode.ParentNode);
}
return currentNode;
}
As you can see from above we get a hold of the current node. If that current node has parents and is not first descendant of a root node – we get a hold it’s parent till we find the root node child.
Good luck!