Export (0) Print
Expand All

How to: Add a Subsite to the Top Link Bar or Quick Launch Menu

SharePoint 2010

Last modified: November 01, 2010

Applies to: SharePoint Foundation 2010

When you create a subsite through the Microsoft SharePoint Foundation user interface, you can specify whether links to the new site appear in the Quick Launch area and the top link bar of the parent site. You can also add links in both places by writing code that manipulates the parent website's SPWeb.Navigation.TopNavigationBar property and its SPWeb.Navigation.QuickLaunch property.

In the SharePoint Foundation object model, the navigation structure for the top link bar is represented by an instance of the SPNavigationNodeCollection class. To get the collection, first access the website's SPWeb.Navigation property, which returns an SPNavigation object, and then access the TopNavigationBar property of that object.

Caution note Caution

If a website is configured to use the top link bar from its parent site, the TopNavigationBar property returns null.

When you have a collection of navigation nodes, construct an SPNavigationNode object to represent the new link, and then call a method of the SPNavigationNodeCollection class to add the node to the top link bar.

To add a link to a subsite on the parent site's top link bar

  1. Get a reference to the SPWeb object that represents the subsite.

    SPWeb child = site.OpenWeb("parent/child");
    
  2. Verify that the subsite is indeed a subsite by testing the value of the IsRootWeb property; also verify that the parent site is not using a shared top link bar by testing the value of its UseShared property.

    if (!child.IsRootWeb && !child.ParentWeb.Navigation.UseShared)
    
  3. Get the SPNavigationNodeCollection object that represents the parent site's top link bar.

    SPNavigationNodeCollection topnav = child.ParentWeb.Navigation.TopNavigationBar;
    
  4. Check for an existing link to the subsite by querying the collection for an SPNavigationNode object that has a Url property that has a value equal to the subsite's SPWeb.ServerRelativeUrl property.

    SPNavigationNode node = topnav
        .Cast<SPNavigationNode>()
        .FirstOrDefault(n => n.Url.Equals(child.ServerRelativeUrl));
    
  5. If no link exists, construct an SPNavigationNode object to represent a link, and call a method from the SPNavigationNodeCollection class to add it to the parent site's top link bar.

    if (node == null)
    {
        node = new SPNavigationNode(child.Title, child.ServerRelativeUrl);
        node = topnav.AddAsLast(node);
    }
    

Example

The following example shows how to add a link to a subsite in the parent site's navigational structure. The example is part of a larger project that uses a web-scoped Feature to add the link. The Feature includes an event handler that implements the SPFeatureReceiver class, and code to create the link and add it to the parent site is in the feature receiver's FeatureActivated method.

If the site where the Feature is activated has subsites, the method looks for a subsite named "ourwiki". If the subsite exists, the method gets a reference to it. If there are no subsites, or there are subsites but none have the name "ourwiki", the method creates one.

Next, the method adds the navigation link to the subsite. If the current site has its own top link bar (that is, it is not using its parent's bar), the link is added to the current site's top link bar. Otherwise, it is added to the current site's Quick Launch menu.

Both Quick Launch and the top link bar are represented by SPNavigationNodeCollection objects. Therefore, at this point the code is the same no matter which collection is the destination for the navigation link. The example first checks whether a link to the subsite is already in the navigation node collection. If it is not, the code creates a link and adds it.

Note Note

The example code uses several types without qualification. For the code to compile correctly, your feature receiver class must import the following namespaces:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{

    // Get the website where the feature is activated.
    SPWeb parentWeb = properties.Feature.Parent as SPWeb;
    if (parentWeb == null)
        return;

    SPWeb childWeb = null;
    string childName = "ourwiki";

    // If a subsite by that name exists, open it.
    string[] webs = parentWeb.Webs.Names;
    if (webs != null && Array.IndexOf(webs, childName) >= 0)
    {
        childWeb = parentWeb.Webs[childName];
    }

    // Otherwise, create the subsite.
    if (childWeb == null)
    {
        string title = "Wiki";
        string desc = "A place to capture knowledge.";
        uint lcid = parentWeb.Language;

        string templateName = "WIKI#0";

        childWeb = parentWeb.Webs.Add(childName, title, desc, lcid, templateName, false, false);
    }

    // Let the subsite use the parent site's top link bar.
    childWeb.Navigation.UseShared = true;

    // Get a collection of navigation nodes.
    SPNavigationNodeCollection nodes = null;
    if (parentWeb.Navigation.UseShared)
    {

        // Parent site does not have its own top link bar
        // so use the parent's Quick Launch.
        nodes = parentWeb.Navigation.QuickLaunch;
    }
    else
    {

        // Parent site has its own top link bar,
        // so use it.
        nodes = parentWeb.Navigation.TopNavigationBar;
    }

    // Check for an existing link to the subsite.
    SPNavigationNode node = nodes
        .Cast<SPNavigationNode>()
        .FirstOrDefault(n => n.Url.Equals(childWeb.ServerRelativeUrl));

    // No link, so add one.
    if (node == null)
    { 

        // Create the node.
        node = new SPNavigationNode(childWeb.Title, childWeb.ServerRelativeUrl);

        // Add it to the collection.
        node = nodes.AddAsLast(node);
    }

    childWeb.Dispose();
    parentWeb.Dispose();
}

In the SharePoint Foundation object model, each navigation link on the Quick Launch menu is represented by an instance of the SPNavigationNode class. The top level of the Quick Launch menu structure is a collection of SPNavigationNode objects represented by an instance of the SPNavigationNodeCollection class. The nodes on this first level of the menu are the headings—List, Libraries, Sites, and so on. Each heading has a SPNavigationNode.Children property that returns a collection of nodes that represent the links below the heading.

To insert a link below the Sites heading, you can call the AddToQuickLaunch method and specify the Sites heading. The method accepts two arguments: an SPNavigationNode object that represents the new link, and an SPQuickLaunchHeading enumeration value that specifies the heading that should receive the link.

SPNavigation nav = web.ParentWeb.Navigation;
SPNavigationNode node = new SPNavigationNode(web.Title, web.ServerRelativeUrl);
node = nav.AddToQuickLaunch(node, SPQuickLaunchHeading.Sites);

You will of course want to check to make sure that a link to the subsite does not already exist below the Sites heading. One way to check is explained in the following procedure.

To add a link to a subsite on the parent site's Quick Launch

  1. Get a reference to the SPWeb object that represents the subsite.

    SPWeb child = site.OpenWeb("parent/child");
    
  2. Verify that the subsite is in fact a subsite and not the root website of the collection.

    if (!child.IsRootWeb)
    
  3. Get the SPNavigation object for the parent website.

    SPNavigation nav = web.ParentWeb.Navigation;
    
  4. Get the Sites heading on the Quick Launch menu by calling the GetNodeById method, passing the integer equivalent of SPQuickLaunchHeading.Sites.

    SPNavigationNode sitesHeading = nav.GetNodeById((int)SPQuickLaunchHeading.Sites);
    
    NoteNote

    If the Quick Launch menu does not yet have a Sites heading, the call to GetNodeById returns null.

  5. Check for an existing link to the subsite by querying the children of the Sites heading for an SPNavigationNode object that has a Url property with a value equal to the subsite's SPWeb.ServerRelativeUrl property.

    SPNavigationNode newNode = null;
    if (sitesHeading != null)
    {
        newNode = sitesHeading
            .Children
            .Cast<SPNavigationNode>()
            .FirstOrDefault(n => n.Url == web.ServerRelativeUrl);
    }
    
  6. If no link exists, construct an SPNavigationNode object to represent the link, and call the AddToQuickLaunch method to add it to the parent site's Quick Launch menu below the Sites heading.

    if (newNode == null)
    {
    
        // Create the link.
        newNode = new SPNavigationNode(web.Title, web.ServerRelativeUrl);
    
        // Add it to the parent site's Quick Launch.
        newNode = nav.AddToQuickLaunch(newNode, SPQuickLaunchHeading.Sites);
    }
    

Example

The following example is a console application that illustrates the procedure for inserting a link to a subsite on the parent site's Quick Launch menu. You could add similar code (suitably modified) in the FeatureActivated method of a Feature receiver that creates a subsite.

using System;
using System.Linq;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Navigation;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SPSite site = new SPSite("http://localhost"))
            {

                // Get the subsite.
                using (SPWeb web = site.OpenWeb("parent/child"))
                {
                    if (!web.IsRootWeb)
                    { 

                        // Get the parent site's navigator.
                        SPNavigation nav = web.ParentWeb.Navigation;

                        // Get the Sites heading.
                        SPNavigationNode sitesHeading = nav.GetNodeById((int)SPQuickLaunchHeading.Sites);

                        // Check if a link to the child already exists.
                        SPNavigationNode newNode = null;
                        if (sitesHeading != null)
                        {
                            newNode = sitesHeading
                                .Children
                                .Cast<SPNavigationNode>()
                                .FirstOrDefault(n => n.Url == web.ServerRelativeUrl);
                        }

                        // No link, so create one.
                        if (newNode == null)
                        {

                            // Create the link.
                            newNode = new SPNavigationNode(web.Title, web.ServerRelativeUrl);

                            // Add it to the parent site's Quick Launch.
                            newNode = nav.AddToQuickLaunch(newNode, SPQuickLaunchHeading.Sites);
                        }

                        Console.WriteLine("A link to {0} is on the Quick Launch for {1}", newNode.Title, nav.Web.Title);
                    }
                }
            }
            Console.Write("\nPress ENTER to continue....");
            Console.ReadLine();
        }
    }
}

Show:
© 2015 Microsoft