SharePoint Navigation Elements: How to Code with them.

I’m a pretty regular poster over on the MSDN SharePoint dev forum and one of the things that I see pop up every so often is questions about how to interact with the Navigation components that are built into SharePoint.

Now you can fiddle with these through the web UI, but really, where is the fun in that? Not to mention the fact that I want software to alter my navigation elements as necessary.

I’ve been working on a large piece of work, part of which includes the automated provisioning of Sites and Site Collections, so I got to spend a little time writing code to alter the navigational elements within my SharePoint instances.

One thing that I’ve found a little annoying was that I couldn’t find a way to ensure that one of the lists in my site definition appeared in the Quick Launch bar, it would appear if I created the site through the UI, but not when I created the new site in code. ๐Ÿ˜

The solution:

SPList submissionsList = newWeb.Lists["Submissions"];
submissionsList.OnQuickLaunch = true;
submissionsList.Update();

Simply set the OnQuickLaunch property of the list, oh and make sure you call Update() ๐Ÿ˜‰

Ok, so what about inserting other links into the Quick Launch and Top Navigation? Luckily it’s pretty easy. The SharePoint object model provides us with the SPNavigationNode and SPNavigationNodeCollection classes.

//get the quicklaunch and top nav for the target Web.
SPNavigationNodeCollection quickLaunchNodes = targetWeb.Navigation.QuickLaunch;
SPNavigationNodeCollection localTopNav = targetWeb.Navigation.TopNavigationBar

Now SharePoint has a few smarts when it comes to navigation nodes, it contains the ability to create navigation nodes that will automatically update their target URL if the that URL maps to a location within the current site collection, this is acheived by passing false as the isExternal parameter in the constructor for the SPNavigationNode.

//create the new node but have WSS maintain this link automagically
SPNavigationNode newNode = new SPNavigationNode(newWeb.Title, newWeb.ServerRelativeUrl, false);

Note that if the URL supplied in the constructor is for a location outside the Site Collection where this SPNavigationNode is to be held the you must pass true for the isExternal parameter, otherwise your code will throw an exception.

Now that you have a new node you can add it directly to the SPNavigationNodeCollection that you wish to using either the AddAsFirst or AddAsLast methods but that’s not going to be all that useful if you want to maintain some form of order…. The SPNavigationNode class contains a Children property, which as you might guess is a SPNavigationNode collection! This notion of nested node collections is how the Quick Launch Bar maintains its orgainisation. So quite often you’ll actually want to find a particular node in the QuickLaunch or TopNavigationBar collections of nodes and add the new node as a child to the desired node.

I created this helper method for this purpose and just made a couple of calls to add the new SPNavigationNode that I created earlier:

//Add the new Navigation node to the QuickLaunch and the TopNav
InsertNavigationNodeToCollectionAsChild(targetWeb, newNode, localTopNav, COURSES_NODE_TITLE);
InsertNavigationNodeToCollectionAsChild(targetWeb, newNode, quickLaunchNodes, "Sites");
 private void InsertNavigationNodeToCollectionAsChild(SPWeb rootWeb, 
                                                          SPNavigationNode nodeToInsert, 
                                                          SPNavigationNodeCollection targetNodeCollection, 
                                                          string parentNodeTitle)
{
     bool hasParentNode = false;
     foreach (SPNavigationNode node in targetNodeCollection)
     {
         if (parentNodeTitle == node.Title)
         {
            //Found the required parent node, add to it, 
            //set up our test variable, update and break from the loop
            hasParentNode = true;
            node.Children.AddAsFirst(nodeToInsert);
            node.Update();
            break;
        }
     }
     if (!hasParentNode)
     {
         //the desired parent node doesn't exist so create it ;o)
         //create as external so that no attempt to maintain is made by WSS
         SPNavigationNode coursesNode = new SPNavigationNode(parentNodeTitle, "", true);
  
         //add the parent at the end of the targetNodeCollection 
         targetNodeCollection.AddAsLast(coursesNode);
         coursesNode.Update();
         //Add our new site collection node to it's parent
         coursesNode.Children.AddAsFirst(nodeToInsert);
         nodeToInsert.Update();
     }
     //call update to make everything 'stick'
     rootWeb.Update();
}

Hope that someone out there finds this useful

Advertisements
This entry was posted in Development, SharePoint. Bookmark the permalink.

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s