Question

Good Morning All, I'm running into an issue where I would like to hide and show links on the quick launch based on a specific SharePoint group. I know how you can do it through the browser, but I'm to do it through code, either through a feature or master page. I do have publishing enabled which allows me to configure both the global and quick launch navigation. My first attempt was to set the "Audience" on link based on a specific SharePoint group (See code below)

SPNavigation spSiteNav = spWeb.Navigation;
SPNavigationNodeCollection spSiteQuickLaunch = spSiteNav.QuickLaunch;
SPNavigationNode spBaseHeading = spWeb.Navigation.QuickLaunch.Cast<SPNavigationNode>().Where(a => a.Title == "I need to").FirstOrDefault();
if (spBaseHeading != null){
    string webAppRelativePath = spWeb.ServerRelativeUrl;

    if (!webAppRelativePath.EndsWith("/")){ webAppRelativePath += "/";}
    string MemPageUrl = string.Format("{0}{1}", webAppRelativePath, "SitePages/CreateNewMemo.aspx");
                        SPNavigationNode MemoPageLink = spBaseHeading.Children.Cast<SPNavigationNode>().Where(a => a.Url == MemPageUrl).FirstOrDefault();
     MemoPageLink.Properties["Audience"] = string.Format(";;;;{0}", "Authors");
     MemoPageLink.Update();
}

No luck, the code sets the audience on the link, but non "Authors" members can still see the link on the quick launch.

Then I tried setting the IsVisible property (See code below):

SPNavigation spSiteNav = spWeb.Navigation;
SPNavigationNodeCollection spSiteQuickLaunch = spSiteNav.QuickLaunch;
SPNavigationNode spBaseHeading = spWeb.Navigation.QuickLaunch.Cast<SPNavigationNode>().Where(a => a.Title == "I need to").FirstOrDefault();
if (spBaseHeading != null){
    string webAppRelativePath = spWeb.ServerRelativeUrl;
    if (!webAppRelativePath.EndsWith("/")){webAppRelativePath += "/";}
    string MemPageUrl = string.Format("{0}{1}", webAppRelativePath, "SitePages/CreateNewMemo.aspx");
    SPNavigationNode MemoPageLink = spBaseHeading.Children.Cast<SPNavigationNode>().Where(a => a.Url == MemPageUrl).FirstOrDefault();
    MemoPageLink.IsVisible = false;
    MemoPageLink.Update();

}

No luck again. The property is set, but the link is still visible to non "Authors" members.

I'm lost, any help would be greatly appreciate.

Thank you in advance....

Was it helpful?

Solution

How to manage audience targeting for Navigation using SSOM

UpdateNavigationNodeAudience method allows to set audience targeting for Navigation node:

 public static void UpdateNavigationNodeAudience(SPWeb web, SPNavigationNode node, Guid[] spAudienceIDs, string[] spGroupNames, string[] adGroupNames)
 {
        var audienceProps = new Dictionary<string, string>();
        audienceProps["SharepointAudienceID"] = spAudienceIDs == null ? string.Empty : string.Join(",", spAudienceIDs.Select(a => a.ToString()).ToArray());
        audienceProps["SharepointGroup"] = spGroupNames == null ? string.Empty : string.Join(",", spGroupNames);
        audienceProps["ActiveDirectoryGroupObjectLDAPPath"] = adGroupNames == null ? string.Empty : string.Join("\n", adGroupNames);
        var audienceValue = string.Format("{0};;{1};;{2}", audienceProps["SharepointAudienceID"], audienceProps["ActiveDirectoryGroupObjectLDAPPath"], audienceProps["SharepointGroup"]);
        node.Properties["Audience"] = audienceValue;
        node.Update();
 }

Note: It has been tested in SharePoint 2010

Example

The below example demonstrates how to target Quick Launch menu nodes to SharePoint Group named Authors:

using (var site = new SPSite(siteUrl))
{
    using (var web = site.OpenWeb())
    {
       var quickLaunch = web.Navigation.QuickLaunch;
       foreach (SPNavigationNode node in quickLaunch)
       {
           var spGroupNames = new[] {"Authors"};
           UpdateNavigationNodeAudience(web, node, null, spGroupNames, null);
       }
    }
 }

About Audience value format in navigation

The value has the following format:

{SharepointAudienceID};;{ActiveDirectoryGroupObjectLDAPPath};;{SharepointGroup}

where

  • {SharepointAudienceID} - SharePoint Audience ID. The delimiter , is used to specify multiple values
  • {ActiveDirectoryGroupObjectLDAPPath} - AD Group Name. The delimiter \n is used to specify multiple values
  • {SharepointGroup} - SP Group Name. The delimiter , is used to specify multiple values

How to hide Pages/Webs from Navigation

Use the following properties to control page/web visibility:

The HidePageFromCurrentNavigation method hides page from current navigation:

    public static void HidePageFromCurrentNavigation(SPWeb web,string pageUrl)
    {
        var publishingWeb = PublishingWeb.GetPublishingWeb(web);
        var query = new SPQuery
            {
                Query = string.Format(@"<Where><Eq><FieldRef Name='FileRef'></FieldRef><Value Type='Text'>{0}</Value></Eq></Where>",pageUrl)
            };
        var pages = publishingWeb.GetPublishingPages(query);
        if (pages.Count == 1)
        {
            pages[0].IncludeInCurrentNavigation = false;
        }
    }

The HideWebFromCurrentNavigation method hides web from current navigation:

    public static void HideWebFromCurrentNavigation(SPWeb parentWeb, string webUrl)
    {
        var web = parentWeb.Webs.FirstOrDefault(w => w.ServerRelativeUrl == webUrl);
        if (web != null)
        {
            var publishingWeb = PublishingWeb.GetPublishingWeb(web);
            publishingWeb.IncludeInCurrentNavigation = false;   
        }
    }

Example

The example demonstrates how to hide all pages and webs from current navigation:

using (var site = new SPSite(siteUrl))
{
    using (var web = site.OpenWeb())
    {
       var quickLaunch = web.Navigation.QuickLaunch;
       foreach (SPNavigationNode node in quickLaunch)
       {
            var nodeType = (string)node.Properties["NodeType"];
            if (nodeType == "Page")  //Page node?
            {
                  HidePageFromCurrentNavigation(web, node.Url);    
            }
            else if (nodeType == "Area")  //Web node?
            {
                  HideWebFromCurrentNavigation(web, node.Url);    
            }
       }
    }
 }

OTHER TIPS

For SharePoint 2013 you need to enable the Site Collection Feature "SharePoint Server Publishing Infrastructure" for audience target to work.

http://community.office365.com/en-us/f/148/t/230976.aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top