Tuesday, September 6, 2011

Customize SharePoint 2010 Global Navigation

The goal of this post is to modify the global navigation of a SharePoint site by using an Event Receiver.
Following Event Receiver will add two new links to the global navigation as the last items of the navigation. New links to be added are picked from the Feature Template file. Here links are separated by “;#” character sequence and display name and the navigation URL are separated by a semicolon. Here I have used SPWeb.Navigation Property, which returns an object that represents navigation on the website, including the Quick Launch area and the top navigation bar.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
string siteURL = ((SPWeb)properties.Feature.Parent).Site.Url;
string newLinksString = string.Empty;
foreach (SPFeatureProperty featureProperty in properties.Feature.Properties)
{
if (featureProperty.Name.Equals("NewLinks"))
{
newLinksString = featureProperty.Value;
}
}
string[] newLinks = newLinksString.Split(new string[] { ";#" },
StringSplitOptions.RemoveEmptyEntries);
using (SPWeb currentWeb = (SPWeb)properties.Feature.Parent)
{
using (SPSite site = currentWeb.Site)
{
using (SPWeb web = site.OpenWeb())
{
SPNavigationNodeCollection globalNavNodes =
web.Navigation.TopNavigationBar;
if (globalNavNodes != null)
{
foreach (string item in newLinks)
{
string[] newLink = item.Split(new string[] { ";" },
StringSplitOptions.RemoveEmptyEntries);
SPNavigationNode newMenuItem =
new SPNavigationNode(newLink[0], newLink[1], true);
globalNavNodes.AddAsLast(newMenuItem);
}
}
web.Update();
}
}
}
}

Following Event Receiver will remove links from the global navigation, which are specified in the Feature Template file in “DeleteLinks” property. Again the links are separated by “;#” character sequence. The value specified for the “DeleteLinks” property is the URL of a site-site called “GroupWork”. Here I have used PublishingWeb.Navigation Property, which returns a PortalNavigation object that represents the navigation settings for the current publishing Web.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
string siteURL = ((SPWeb)properties.Feature.Parent).Site.Url;
string linksStringToRemove = string.Empty;
foreach (SPFeatureProperty featureProperty in properties.Feature.Properties)
{
if (featureProperty.Name.Equals("DeleteLinks"))
{
linksStringToRemove = featureProperty.Value;
}
}
string[] linksToRemove = linksStringToRemove.Split(new string[] { ";#" },
StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < linksToRemove.Length; i++)
{
siteURL = string.Concat(siteURL.TrimEnd('/'), "/",
linksToRemove[i].TrimStart('/'));
using (SPSite site = new SPSite(siteURL))
{
using (SPWeb rootWeb = site.RootWeb)
{
using (SPWeb web = site.OpenWeb())
{
if (PublishingWeb.IsPublishingWeb(rootWeb))
{
PublishingWeb publishingWeb =
PublishingWeb.GetPublishingWeb(rootWeb);
publishingWeb.Navigation.ExcludeFromNavigation(true, web.ID);
publishingWeb.Update();
}
}
}
}
}
}

My Feature Template file contains two properties specifying what the links to be added are and what are the links to be removed. Here links are separated by “;#” character sequence.

Feature.Template.xml
<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/">
<Properties>
<Property Key="DeleteLinks" Value="/GroupWork"/>
<Property Key="NewLinks" Value="WebMail;https://webmail.abcde.org/owa;#
SharePoint eLearning;
http://www.microsoft.com/learning/en/us/training/sharepoint.aspx"
/>
</Properties>
</Feature>

Note: Publishing features needs to be activated in order to use the Event Receiver for removing links. Also it will only work if the feature is activated after creating the site. It won’t work as expected, if we try to activate it by onet.xml as still the site structure is being created.