ORIGINAL POST: 12/09/06
Ok, so I m back again. I have been mega busy with all sorts of stuff but found some time to write a little post about programmatically modifying the Navigation Bar in MOSS2007. Before I begin, if you want a full in-depth post then wander over to Todd Baginski's blog and check out the MOSS2007 How to section.
So to begin for this sample I will be using my team site which is located at http://portal.labs.demo.local/design. I will also be creating a new ASP.NET website which is created in:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS
The purpose of this s purely to demonstrate the code I will be writing. So let's dive straight in. The navigation menu on the left of the page is basically an ASP.NET Menu control with some extra bit and pieces on it. Because it is based on a normal ASP.NET Menu control you can use standard syntax to add new items and groups of items. To begin let's look at adding a top level menu item. Launch Visual Studio 2005 if you have not already and open up the ASP.NET Website you have created. I will be using C# for the code. Add the following code as below into the "Page_Load" event.
NOTE: You will need to add the following directives at the top of the page:
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Navigation;
You will also need to add a reference to Microsoft.SharePoint.dll which can be found here:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI
The code we will add is:
SPSite siteDemoCollection = SPControl.GetContextSite(Context);
SPWeb siteDemo = siteDemoCollection.AllWebs["Design"];
siteDemo.AllowUnsafeUpdates = true;
SPNavigationNodeCollection nodesDemo = siteDemo.Navigation.QuickLaunch;
SPNavigationNode navDemoNode = new SPNavigationNode("Custom Menu", "http://www.microsoft.com", true);
nodes.AddAsFirst(navNode);
siteDemo.Update();
This code simply gets the current site context, connects to the "Design" team site, allows updates as we are making changes to the site. It then connects to the Navigation object and adds a new top level node called "Custom Menu" and sets the link to the Microsoft Website. The "True" flag at the end is used to tell the component if this link is an external or internal URL. In our case it is set to "True" as t is an external link. If we now compile the page and browse to it, and then open up the "Design team site it should look as below:
Now that we have added a top level heading, now we can change the code to remove the heading. This uses the same code as above except we remove the last but one line and add the following:
nodesDemo.Delete(nodesDemo[0]);
As you can see you simply need to call the delete method and pass it the ID level of the menu item you wish to remove. The full code for delete should have read:
SPSite siteDemoCollection = SPControl.GetContextSite(Context);
SPWeb siteDemo = siteDemoCollection.AllWebs["Design"];
siteDemo.AllowUnsafeUpdates = true;
SPNavigationNodeCollection nodesDemo = siteDemo.Navigation.QuickLaunch;
nodesDemo.Delete(nodesDemo[0]);
siteDemo.Update();
If you want to add some sub menu items to our new menu the code block should be as below:
SPSite siteDemoCollection = SPControl.GetContextSite(Context);
SPWeb siteDemo = siteDemoCollection.AllWebs["Design"];
siteDemo.AllowUnsafeUpdates = true;
SPNavigationNodeCollection nodesDemo = siteDemo.Navigation.QuickLaunch;
SPNavigationNode navDemoNode = new SPNavigationNode("Custom Menu", "#", false);
nodesDemo.AddAsFirst(navDemoNode);
SPNavigationNode subnavDemoNode1 = new SPNavigationNode("Menu Item 1", "http://beta.microsoft.com", true);
nodesDemo[0].Children.AddAsFirst(subnavDemoNode1);
SPNavigationNode subnavDemoNode2 = new SPNavigationNode("Menu Item 2", "http://connect.microsoft.com", true);
nodesDemo[0].Children.AddAsFirst(subnavDemoNode2);
siteDemo.Update();
This renders itself as:
As you can see it is really stratight forward to create new custom menus programmatically. This applies to the top navigation also. (See Todds Article for this.). The beauty of this method is that you can use normal data sources programatically to add new menus. I have an XML file that I wish to use as the structure for my menus, if we modify the code slightly we can then get all the menus drawn automatically. The XML I am using is:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.labs.demo.local/MOSS2007/SiteMap" >
<siteMapNode title="CustomMenu" url="CustomMenu.aspx" Level="1">
<siteMapNode title="Menu Link 1" url="MenuLink1.aspx" Level="2" />
<siteMapNode title="Menu Link 2" url="MenuLink2.aspx" Level="2" />
<siteMapNode title="Menu Link 3" url="MenuLink3.aspx" Level="2" />
<siteMapNode title="Menu Link 4" url="MenuLink4.aspx" Level="2" />
<siteMapNode title="Menu Link 5" url="MenuLink5.aspx" Level="2" />
<siteMapNode title="Menu Link 6" url="MenuLink6.aspx" Level="2" />
</siteMapNode>
</siteMap>
This XML file is one that I used in the previous post on customising menu bars. I have re-written the code as below to draw the menu automatically.
SPSite siteDemoCollection = SPControl.GetContextSite(Context);
SPWeb siteDemo = siteDemoCollection.AllWebs["Design"];
siteDemo.AllowUnsafeUpdates = true;
SPNavigationNodeCollection nodesDemo = siteDemo.Navigation.QuickLaunch;
XmlTextReader reader = new XmlTextReader(@"XMLFile.xml");
while (reader.Read())
{
if (reader.GetAttribute("Level") == "1")
{
SPNavigationNode navDemoNode = new SPNavigationNode(reader.GetAttribute("title"), reader.GetAttribute("url"), true);
nodesDemo.AddAsFirst(navDemoNode);
}
else
{
SPNavigationNode subnavDemoNode = new SPNavigationNode(reader.GetAttribute("title"), reader.GetAttribute("url"), true);
nodesDemo[0].Children.AddAsFirst(subnavDemoNode);
}
}
siteDemo.Update();
}
I know there are better ways of witing this but for testing this will suffice. If we now run the page of our custom website and then launch the Team Site it should look like this:
So as you can see with very little code you can create your own menus. These menus can simply be added via the UI, added by using Data Sources in SharePoint Designer or by programatically adding either static or dynamic items from a data source. If you are building applications on MOSS2007 there are many ways of enhancing the user experience with menus and using the power of MOSS2007 quite easily. Hope this is useful.