Programmatically customize site navigation in WSS 3.0 and MOSS 2007

on Saturday, September 20, 2008

HOW TO: Programmatically customize site navigation in WSS 3.0 and MOSS 2007
Note: This is a repost of an article I posted while WSS 3.0 and MOSS 2007 were in the Beta stages. The article was lost due to a server crash and many people have asked me to repost the article so I updated it with additional information, updates screen shots, and a handy little Windows Forms Application you can use to test these concepts out yourself, or build upon the code base to meet your own needs. Enjoy!

In the previous version of SharePoint the QuickLaunch menu was controlled via the ONET.XML file and ASPX pages that made up a Site Definition, and making changes to the QuickLaunch menu was a cumbersome task at best.

The new version of SharePoint provides significant improvements to the navigational elements within a SharePoint site as well as the ability to change these elements programmatically! This article describes how to programmatically interact with the navigation elements via the WSS API in order to customize SharePoint site navigation. This article also investigates the security trimming capabilities of the SharePoint UI with respect to programmatically edited navigation links.

The first thing to note is that the objects used to programmatically customize navigation reside in the Microsoft.SharePoint.Navigation namespace. So, you’ll need to add a reference to the Microsoft.SharePoint.dll in your Visual Studio projects.

New item: Controlling navigation via the SPWeb object!


The SPWeb object has been enhanced in MOSS 2007 to support the ability to control the navigation of a SharePoint site programmatically! Let’s examine how this can be done.

The SPWeb object has a new property named Navigation that returns a SPNavigation object. This object allows developers to programmatically control the navigation of a SharePoint site.

Shared Navigation Settings


One of the new settings you may apply to a site’s navigation structure is whether or not the site uses the navigation menus from its parent site.

These examples assume you have created a top level site named test and a sub site named sharednav under the test top level site as well as a sub site named nosharednav under the test top level site. Once these sites have been created their hierarchy and URLs will look like this:



Before we get started, to help set the stage, here is what the navigation looks like in the test site.



Here is an example of how to set a sub site to use the navigation from its parent site.

SPSite sharedNavSite = new SPSite(“http://server/test/sharednav”);

SPWeb sharedNavWeb = sharedNavSite.OpenWeb();

sharedNavWeb.Navigation.UseShared = true;

The navigation for the sharednav site looks like this after the lines of code above have been run to set the property. Notice the breadcrumb trail at the top of the page uses the breadcrumb trail for the test top level site and the horizontal menu bar uses the items from the test top level site as well.



Here is an example of how to set a sub site not to use the navigation from a parent’s site.

SPSite noSharedNavSite = new SPSite(“http://server/test/nosharednav”);

SPWeb noSharedNavWeb = noSharedNavSite.OpenWeb();

noSharedNavWeb.Navigation.UseShared = false;

The navigation for the nosharednav site looks like this after the lines of code above have been run to set the property. Notice the breadcrumb trail at the top of the page uses the breadcrumb trail for the nosharednav sub site and the horizontal menu bar uses the items from the nosharednav sub site.



QuickLaunch Menu Items

The QuickLaunch navigation menu may also be accessed programmatically. You can create new menu items in the QuickLaunch navigation menu and remove them. You can also specify if the link is external to the site.

Here is how you add a menu item to the QuickLaunch navigation menu.

These QuickLaunch examples assume you have created a top level site named quicklaunch.

Once this top level site has been created its URL will look like this: http://server/quicklaunch

In this example we will add two links to the QuickLaunch menu for the quicklaunch top level site, one link will be internal and one will be external. The internal link will point to the Links list in the QuickLaunch site. The external link will point to the SharePoint Experts web site.

SPSite quickLaunchSite = new SPSite(“http://server/quicklaunch”);

SPWeb quickLaunchWeb = quickLaunchSite.OpenWeb();

SPNavigationNodeCollection quickLaunchNodes = quickLaunchWeb.Navigation.QuickLaunch;

SPNavigationNode internalMenuItem = new SPNavigationNode(“Links”, “Lists/Links/AllItems.aspx”, false);

quickLaunchNodes.AddAsFirst(internalMenuItem);

SPNavigationNode externalMenuItem = new SPNavigationNode(“SharePoint Experts”, “http://www.SharePointExperts.com”, true);

quickLaunchNodes.AddAsFirst(externalMenuItem);

quickLaunchWeb.Update();

*Note: If you do not call the Update() method on the SPWeb object you are working with, you will need to reset IIS to see your changes.

Here is what the quicklaunch Site Collection looks like after the above code has been executed:



Here is how you remove a menu item from the QuickLaunch navigation menu.

In this example we will remove the external link to the SharePoint Experts web site.

SPSite quickLaunchSite = new SPSite(“http://server/quicklaunch”);

SPWeb quickLaunchWeb = quickLaunchSite.OpenWeb();

SPNavigationNodeCollection quickLaunchNodes = quickLaunchWeb.Navigation.QuickLaunch;

quickLaunchNodes.Delete(quickLaunchNodes([0]));

quickLaunchWeb.Update();

Here is what the quicklaunch Site Collection looks like after the above code has been executed:



Taking the QuickLaunch menu one step further


The QuickLaunch menu is capable of displaying links in a grouped fashion, as you see in the screenshot above. For example, the Lists menu item in the screenshot above has two items under it – the Calendar and Tasks links. Creating your own grouped links can be done programmatically. This is once again a simple process that requires very little code.

Here is how you add grouped menu items to the QuickLaunch navigation menu.

In this example we will create a header link for the group of links and name it Administration. Then we will add two links under the Administration header link. The links will link to the Create and Site Settings pages for the quicklaunch Site Collection.

SPSite quickLaunchSite = new SPSite("http://" + serverTextBox.Text + "/quicklaunch");

SPWeb quickLaunchWeb = quickLaunchSite.OpenWeb();

SPNavigationNodeCollection quickLaunchNodes = quickLaunchWeb.Navigation.QuickLaunch;

SPNavigationNode internalMenuItem = new SPNavigationNode("Administration", "", false);

quickLaunchNodes.AddAsFirst(internalMenuItem);

SPNavigationNode externalSubMenuItem1 = new SPNavigationNode("Site Settings", quickLaunchWeb.Url + "/_layouts/settings.aspx", true);

quickLaunchNodes[0].Children.AddAsFirst(externalSubMenuItem1);

SPNavigationNode externalSubMenuItem2 = new SPNavigationNode("Create", quickLaunchWeb.Url + "/_layouts/create.aspx", true);

quickLaunchNodes[0].Children.AddAsFirst(externalSubMenuItem2);

quickLaunchWeb.Update();

Here is what the quicklaunch Site Collection looks like after the above code has been executed:



*Note: I added the Create and Site Settings links to the QuickLaunch bar to test the security trimmed aspects of the SharePoint UI. I wanted to see if SharePoint would hide these links from users who did not have access to see them because MOSS 2007 hides these links in the out of the box SharePoint UI from users who only have reader access.

I created a user named reader and granted the user read only access to the quicklaunch top level site. When I logged into the quicklaunch top level site with this user the links I just added to the QuickLaunch were available to the reader user! This is an important thing to note, and should be kept in mind when adding links to the QuickLaunch menu!

Here is what the quicklaunch Site Collection looked like when the reader user logged in:



Here is the screen you see when you click one of the links you do not have access to:




Top Navigation Menu Items

The top navigation menu may also be accessed programmatically. You can create new menu items in the top navigation menu navigation menu and remove them. You can also specify if the link is external to the site.

Here is how you add a menu item to the top navigation menu.

This example assumes you have created a top level site named topnavigation.

Once this Site Collection has been created its URLs will look like this: http://server/topnavigation

In this example we will add two links to the top navigation menu for the topnavigation top level site, one link will be internal and one will be external. The internal link will point to the Links list in the topnavigation site. The external link will point to the SharePoint Experts web site.

SPSite topNavigationSite = new SPSite(“http://server/topnavigation”);

SPWeb topNavigationWeb = topNavigationSite.OpenWeb();

SPNavigationNodeCollection topNavigationNodes = topNavigationWeb.Navigation.TopNavigationBar;

SPNavigationNode internalMenuItem = new SPNavigationNode(“Links”, “Lists/Links/AllItems.aspx”, false);

topNavigationNodes.AddAsFirst(internalMenuItem);

SPNavigationNode externalMenuItem = new SPNavigationNode(“SharePoint Experts”, “http://www.SharePointExperts.com”, true);

topNavigationNodes.AddAsFirst(externalMenuItem);

topNavigationWeb.Update();

Here is what the topnavigation top level site looks like after the above code has been executed:



Here is how you delete a menu item from the top navigation menu. In this example we will remove the Links link we just added to the top navigation menu for the topnavigation top level site.

SPSite topNavigationSite = new SPSite(“http://server/topnavigation”);

SPWeb topNavigationWeb = topNavigationSite.OpenWeb();

SPNavigationNodeCollection topNavigationNodes = topNavigationWeb.Navigation.TopNavigationBar;

topNavigationNodes.Delete(topNavigationNodes[0]);

topNavigationWeb.Update();

Here is what the topnavigation top level site looks like after the above code has been executed:



Taking the Top Navigation one step further


The top Navigation menu is capable of displaying dropdown menus that consist of multiple items. Adding additional sub menu items under the topmost item is a simple process and requires very little code.

Here is how you add a sub menu item to a top level menu item in the top navigation menu. In this example we will add a new top level menu item to the top navigation menu that has two sub menu items under it for the topnavigation top level site.

SPSite topNavigationSite = new SPSite(“http://server/topnavigation”);

SPWeb topNavigationWeb = topNavigationSite.OpenWeb();

SPNavigationNodeCollection topNavigationBarNodes =

topNavigationWeb.Navigation.TopNavigationBar;

SPNavigationNode headerMenuItem = new SPNavigationNode("SharePoint Sites", "", false);

topNavigationBarNodes.AddAsFirst(headerMenuItem);

SPNavigationNode externalSubMenuItem1 = new SPNavigationNode("SharePoint Experts", "http://www.SharePointExperts.com", true);

topNavigationBarNodes[0].Children.AddAsFirst(externalSubMenuItem1);

SPNavigationNode externalSubMenuItem2 = new SPNavigationNode("SharePoint University", "http://www.SharePointU.com", true);

topNavigationBarNodes[0].Children.AddAsFirst(externalSubMenuItem2);

topNavigationWeb.Update();

Here is what the topnavigation top level site looks like after the above code has been executed:



*Note: I was curious to see if the Top Navigation menu reacted the same way the QuickLaunch menu bar did regarding the security trimming of the UI. So I created an Administration Header link and two sub links for the Create and Site Settings pages.

I granted the reader user read only access to the topnavigation top level site and when I logged into the topnavigation top level site with this user the links I just added to the Top Navigation menu were available to the reader user! This is an important thing to note, and should be kept in mind when adding links to the Top Navigation menu!

Here is the code I used to add the links:

SPSite topNavigationSite = new SPSite(“http://server/topnavigation”);

SPWeb topNavigationWeb = topNavigationLaunchSite.OpenWeb();

SPNavigationNodeCollection topNavigationBarNodes =

topNavigationWeb.Navigation.TopNavigationBar;

SPNavigationNode headerMenuItem = new SPNavigationNode("Administration", "", false);

topNavigationBarNodes.AddAsFirst(headerMenuItem);

SPNavigationNode externalSubMenuItem1 = new SPNavigationNode("Site Settings", topNavigationWeb.Url + "/_layouts/settings.aspx", true);

topNavigationBarNodes[0].Children.AddAsFirst(externalSubMenuItem1);

SPNavigationNode externalSubMenuItem2 = new SPNavigationNode("Create", topNavigationWeb.Url + "/_layouts/create.aspx", true);

topNavigationBarNodes[0].Children.AddAsFirst(externalSubMenuItem2);

topNavigationWeb.Update();

Here is what the topnavigation top level site looked like when the administrator or the reader user user logged in; the links appear for both users.



I created a handy little Windows Forms Application you can use to test these concepts out yourself, or build upon the code base to meet your own needs. The application is easy to use, just enter the name of your SharePoint server, then click the buttons from top to bottom and follow along with this article. The application looks like this:



I hope this article and the application come in handy for you! Now, it’s time to go skiing! :)

0 comments: