When implementing solutions for Microsoft Office SharePoint Server 2007 Publishing (WCMS) sometimes you have to implement a custom navigation. Therefore the object model offers

  • Microsoft.SharePoint.Navigation
  • Microsoft.SharePoint.Publishing.Navigation

which can be found at:

  • Microsoft.SharePoint.dll
  • Microsoft.SharePoint.Publishing.dll

SharePoint 2007 Publishing Navigation

Basics

If you create a Publishing site you can modify the navigation as shown in the following pictures:

Accessing the publishing site navigation page. Modifiying the publishing site navigation.

While creating a publishing site the "Portal Navigation Properties" feature is called. You can find the call of the feature in one of the different onet.xml files used for Publishing. Please note that there is more than one Publishing site template and site definition.

C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates\PUBLISHING\XML\onet.xml

<FeatureID="541F5F57-C847-4e16-B59A-B31E90E6F9EA">
<!-- Per-Web Portal Navigation Properties-->
  <Propertiesxmlns="http://schemas.microsoft.com/sharepoint/">     
<
PropertyKey="InheritGlobalNavigation"Value="true"/>     <PropertyKey="ShowSiblings"Value="true"/>     <PropertyKey="IncludeSubSites"Value="true"/> </Properties> </Feature>

As you can see there a properties like "ShowSiblings" you can set during the call. The "Portal Navigation Properties" feature is stored at the following location:

C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\NavigationProperties\feature.xml

<Feature  Id="541F5F57-C847-4e16-B59A-B31E90E6F9EA"
          Title="Portal Navigation Properties"
          Description="Set per-site navigation properties."
          Version="12.0.0.0"
	  Scope="Web"
	  Hidden="TRUE"
	  ReceiverAssembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, 
                             Culture=neutral, PublicKeyToken=71e9bce111e9429c"
          ReceiverClass="Microsoft.SharePoint.Publishing.NavigationFeatureHandler"
          xmlns="http://schemas.microsoft.com/sharepoint/">
    <ElementManifests>
        <ElementManifestLocation="NavigationSiteSettings.xml"/>
    </ElementManifests>
</Feature>

Changing the properties in onet.xml affects the settings. Please note: It is not recommended to change out of the box files. If you want to test it you do an iisreset in order to make sure the changes apply when you create a new publishing site.

Mapping of the onet.xml feature call and properties to the SharePoint publishing site navigation menu. 

Microsoft.SharePoint.Navigation

Programmatically accessing current navigation in SharePoint Publishing

Depending on the needs of your customer it might be necessary to implement a custom solution.

There are different ways to access the current navigation. The namespace

using Microsoft.SharePoint.Navigation;

offers objects like SPNavigationNodeCollection or SPNavigationNode. I tried it this way but it didn't work for me and my scenario.

if (PublishingWeb.IsPublishingWeb(ElevatedSite))
{     
PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(ElevatedSite);
    SPNavigationNodeCollection nodeColl = pubWeb.CurrentNavigationNodes;    
    foreach (SPNavigationNode node in nodeColl)     
{        
        //The following statement allways returns true        
        if (node.IsVisible)        
        { }
 
      //The object will be null        
        object test = node.Properties["vti_nonnavpage"];    
    }
}

First of all I had to modify the navigation at the publishing site before it showed up in the nodeColl. Second it is not possible the determine if a site or page is hidden because the property "vti_nonnavpage" is not in the property bag of the SPNavigationNode "node" and therefore the getter of property "IsVisible" always returns true.

The getter is implemented to return true if it can't find the property. Because of that I tried the PortalSiteMapProvider.

Microsoft.SharePoint.Publishing.Navigation

Programmatically accessing current navigation in SharePoint Publishing with the ProtalSiteMapProvider

You can find the PortalSiteMapProvider in the namespace

using Microsoft.SharePoint.Publishing.Navigation;

In order to get the current navigation you can use the following code:

PortalSiteMapProvider map = new PortalSiteMapProvider();
SiteMapNodeCollection nodeColl = map.CurrentNode.ChildNodes;
	
foreach (SiteMapNode childNode in nodeColl)
{     
    //childNode.Title;    
    //childNode.Key;     
    //childNode.Url;
}

This code returns a sorted list without the navigation nodes which are hided. You can also access a certain node by using the method FindSiteMapNode with an Url as the parameter.

PortalSiteMapProvider map = new PortalSiteMapProvider();
SiteMapNode node = map.FindSiteMapNode("/PressReleases");
SiteMapNodeCollection nodeColl = node.ChildNodes;
	
foreach (SiteMapNode childNode in nodeColl)
{    
    //Your code...
} 

For me and my scenario the PortalSiteMapProvider was the way to go. And: You can avoid the problems when using the IsVisible property.

That's it for today... ;)


Get FREE & Advanced SharePoint Training, how-to's, tips & tricks:
Learn SharePoint

Comments (5) -

2/4/2009 4:07:16 PM #

Tania

fantastic! just what i needed!

cheers!

Tania Portugal Reply

8/20/2009 3:51:01 PM #

AMol Gore

Superb!!!!!
Just what I needed ..
keep posting

AMol Gore India Reply

10/20/2009 8:15:44 PM #

Libi

Hi,

I used the object just the way you did:

[quote]PortalSiteMapProvider siteMapProvider = new PortalSiteMapProvider();

siteMapProvider.IncludeAuthoredLinks = true;
siteMapProvider.IncludeHeadings = false;
siteMapProvider.IncludePages = PortalSiteMapProvider.IncludeOption.Never;
siteMapProvider.IncludeSubSites = PortalSiteMapProvider.IncludeOption.Always;
siteMapProvider.NavigationType = PortalNavigationType.Current;

SiteMapNode rootNode = siteMapProvider.RootNode;

foreach (SiteMapNode mainNode in rootNode.ChildNodes)
{
...
}
[/quote]

The problem was, that all nodes which are not hidden are belonging to this collection. Unfortunately also just created "mainNodes" where the default-page is still not checked in.

I could fix this by changing the first line of the code above to
[quote]PortalSiteMapProvider siteMapProvider = PortalSiteMapProvider.CurrentNavSiteMapProvider;[/quote]

Best regards, Libi

Libi Austria Reply

1/22/2010 12:47:28 PM #

Roli

That's great! Thanks a lot, Andreas + Libi!

Roli Switzerland Reply

8/9/2012 10:29:06 AM #

Rajesh Chouhan

What an ultimate solution.. I wasted on whole day struggling with Spnavigation nodes coding... Also it always giving child node count 0.. also isvisible always true...

This is perfect solution... Thanks allot... Wonderful information...

Rajesh Chouhan India Reply

Pingbacks and trackbacks (1)+

Add comment


Loading