I recently encountered a strange behavior in MOSS API. In one of my recent projects I had to hide sub-sites from current navigation (Left Navigation) programmatically, so I searched the SDK and came across a nice little property on “SPNavigationNode” object called “IsVisible”. According to SDK documentation, this property allows setting visibility of SharePoint navigation node to visible (true) or hidden (false).
Figure 1: SPNavigationNode SDK documentation
So I tried to loop thru all “SPNavigationNode” objects in current Navigation nodes and looked for property named “Area” in each node’s “Properties” hash-table collection. The sub-sites in MOSS navigation API are represented by node type “Area”. Those of you who have worked with SharePoint Portal Server 2003 (SPS) in the past may recognize the word “Area”. I believe this MOSS property got it roots from SPS and therefore it is named “Area”. Anyway, what was truly surprising to me was that regardless of a node type and its visibility setting the API always returned true.
So what’s the point of “IsVisible” property on “SPNavigationNode” object? I don’t know; I believe that it is a bug in MOSS API and I hope that SharePoint team will address this bug soon. The good news is that there are other ways to do this via the same MOSS API. The way API is designed for navigation is not very intuitive (at least to me), but it works. The code snippets below will show how to hide sites from current navigation and top navigation programmatically.
You will need reference to SharePoint assembly, SharePoint navigation assembly and SharePoint publishing assembly and the following using statements:
Listing 1:
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
using Microsoft.SharePoint.Navigation;
Listing 2:
// This code will run but not hide any current navigation nodes
// “SPNavigationNode” nodes will still show true even after executing this code.
using (SPSite site = new SPSite(“http://SharePoint”))
{
using (SPWeb rootWeb = site.RootWeb)
{
PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(rootWeb);
foreach (SPNavigationNode node in publishingWeb.CurrentNavigationNodes)
{
node.IsVisible = false;
}
publishingWeb.Update();
rootWeb.Update();
}
}
Listing 3:
// This works!
// Hide all subsites from current navigation
// publishingWeb is PublishingWeb object
foreach (PublishingWeb childSite in publishingWeb.GetPublishingWebs())
{
publishingWeb.ExcludeFromNavigation(false, childSite.Web.ID);
}
Listing 4:
// This works!
// Hide all subsites from global (top) navigation
// publishingWeb is PublishingWeb object
foreach (PublishingWeb childSite in publishingWeb.GetPublishingWebs())
{
publishingWeb.ExcludeFromNavigation(true, childSite.Web.ID);
}
HTH,
Talha