Modifying navigation elements through code is quite tricky in WSS 3.0.  Here are few scenarios, I’ve tried to cover that I think will be helpful in playing around with WSS 3.0 navigation elements.  I’ve used the top navigation bar in these examples.  But the same code should work for quick launch as well.

 

BTW: Being in Microsoft SharePoint Developer support, I figure quick launch customization is quite popular J

 

 

Add simple navigation nodes

 

Here’s my previous post on this scenario.  Below is how you can add top navigation nodes for non-SharePoint sites.

 

            using (SPSite site = new SPSite("<sharepoint site url>"))

            {

                using (SPWeb web = site.OpenWeb())

                {

                    SPNavigationNodeCollection nodes = web.Navigation.TopNavigationBar;

                    SPNavigationNode newNode1 = new SPNavigationNode("MS TechNet", "http://technet.microsoft.com", true);

                    SPNavigationNode newNode2 = new SPNavigationNode("SharePoint SDK Online", "http://msdn.microsoft.com/sharepoint", true);

                    nodes.AddAsFirst(newNode2);

                    nodes.AddAsLast(newNode1);

                    MessageBox.Show("Nodes added");

                }

            }       

 

This adds very simple top navigation nodes, one at the start and the other at the end.

 

Note: If the node you are adding is not a sub-site within that particular site collection, you must instantiate the SPNavigationNode object as highlighted above.  The URL attribute must begin with “http://” and isExternal attribute must be set to true.

 

If isExternal attribute is not set or set to false, the OM at runtime adds a “/” before the URL attribute you provide.  So, if you provide "http://technet.microsoft.com" it becomes “/http://technet.microsoft.com” and will error out.

 

If the URL attribute is provided like “www.microsoft.com”, SharePoint injects the root site collection URL and the result will become “http://<sharepoint site url>/www.microsoft.com” – which is wrong!

 

 

A bit tricky navigation node addition/modification

 

To add node “between” those that are already present, use a code like the following:

 

using (SPSite site = new SPSite("<sharepoint site url>"))

            {

                using (SPWeb web = site.OpenWeb())

                {

                    SPNavigationNodeCollection nodes = web.Navigation.TopNavigationBar;

                    SPNavigationNode newNode = new SPNavigationNode("SilverLight 2.0", "http://silverlight.net",true); // test

                    SPNavigationNode preNode1 = nodes.Navigation.GetNodeByUrl("/Sub1/default.aspx");

                    foreach (SPNavigationNode preNode2 in nodes)

                    {

                        if (preNode2.Url == "http://msdn.microsoft.com/sharepoint")

                        {

                            nodes.Add(newNode, preNode2);

                            break;

                        }

                    }

                    nodes.Add(newNode, preNode1);

                    MessageBox.Show("Node adjusted");

                }

            }

 

 

Note: The one highlight in green shows how to add a node after a node that’s NOT a node pointing to a sub-site within that site collection.  The one highlighted in pink shows how to add a node after a node that’s a node pointing to a sub-site within that site collection.

 

 

Rearrange navigation nodes

 

Check out my previous post on sorting quick launch.  You can do rearrangement that way.  I have used alphabetical order, but that can be done using any measurable parameter that we can use as a reference.

 

A customer sent me the below code:

 

            using (SPSite site = new SPSite("<sharepoint site url>"))

            {

                using (SPWeb web = site.OpenWeb())

                {

                    SPNavigationNodeCollection nodes = web.Navigation.TopNavigationBar;

                    SPNavigationNode delNode = nodes.Navigation.GetNodeByUrl("/Sub4/default.aspx");

                    nodes.Delete(delNode);

                    SPNavigationNode newNode = new SPNavigationNode("Sub4", "/Sub4/default.aspx");

                    SPNavigationNode preNode = nodes.Navigation.GetNodeByUrl("/Sub1/default.aspx");

                    nodes.Add(newNode, preNode);                   

                    MessageBox.Show("Rearranged");

                   

                }

            }       

 

While the above code looks good, the SPNavigationNode object provides three variations of “Move” methods as SPNavigationNodeCollection does for “Add”.  Below is a sample:

 

using (SPSite site = new SPSite("<sharepoint site url>"))

            {

                using (SPWeb web = site.OpenWeb())

                {

                    SPNavigationNodeCollection nodes = web.Navigation.TopNavigationBar;                   

                    SPNavigationNode nodeToMove = nodes.Navigation.GetNodeByUrl("/Sub4/default.aspx");                   

                    SPNavigationNode preNode = nodes.Navigation.GetNodeByUrl("/Sub1/default.aspx");

                    nodeToMove.Move(nodes, preNode);

                    MessageBox.Show("Rearranged");

                   

                }

            }

 

All the other rearrangement can be carried out in the same manner.

 

 

Deleting a node

 

We have to carefully use the SPNavigationNodeCollection for this.  As any other collection in SharePoint, if we directly loop through this collection using a foreach loop, we’ll run into code failures because of change in the collection that’s being enumerated.  So, use a for loop to run through the total number of SPNavigationNode in the collection.  And then, based on some checks, delete the nodes.  Sample below:

 

            using (SPSite site = new SPSite("<sharepoint site url>"))

            {

                using (SPWeb web = site.OpenWeb())

                {

                    SPNavigationNodeCollection nodes = web.Navigation.TopNavigationBar;

                    for (int i = nodes.Count-1; i >= 0; i--)

                    {

                        if (nodes[i].Url.Equals("http://silverlight.net"))

                        {

                            nodes[i].Delete();

                        }

                    }

                    MessageBox.Show("Node(s) deleted");

                }

            }       

 

 

To Summarize

 

Navigation in WSS 3.0 is far more extensible and customizable than it was in WSS 2.0.  The sample show above should work for quick launch navigation without problems.  MOSS 2007 sites follow a different navigation approach.  More details in my previous post.