Adding Links to Quick Launch

Applies to: SharePoint Foundation 2010

On a Microsoft SharePoint Foundation website, Quick Launch is the static menu on the left side of most content pages. The SharePoint Foundation object model represents the Quick Launch menu as a hierarchy of SPNavigationNode objects, with each object representing a hypertext link on the menu.

Adding a new link to the menu is a matter of constructing an object to represent the link and then adding it in the right place in the hierarchy.

At the top level of the Quick Launch menu are the headings. You can get the collection of headings by first getting the object that is returned by the Navigation property of the website and by then getting the QuickLaunch property of that object. The QuickLaunch property returns an SPNavigationNodeCollection object that contains the set of SPNavigationNode objects that represent the headings.

SPNavigationNodeCollection ql = web.Navigation.QuickLaunch;
Dim ql As SPNavigationNodeCollection = web.Navigation.QuickLaunch

At the next level down are items below headings. Each SPNavigationNode object that represents a heading has a Children property that can contain a collection of nodes that represent items below a heading. If no items are below a heading, the Children property of the heading node returns an empty collection.

foreach (SPNavigationNode heading in web.Navigation.QuickLaunch)
{
    foreach (SPNavigationNode item in heading.Children)
    {

        // Do something.
    }
}
For Each heading As SPNavigationNode In web.Navigation.QuickLaunch
    For Each item As SPNavigationNode In heading.Children

        ' Do something.
    Next
Next

The heading and each item below it are SPNavigationNode objects that represent hypertext links. Display text for each link is encapsulated in the Title property of the object, and the link's URL is in the Url property of the object. The values for these properties are independent of the link's target. If the link points to a website and the site's title or URL changes, the title and URL in the navigation node do not automatically change also.

By default, the Quick Launch menu is configured to show only two levels. You can customize Quick Launch so that additional levels can appear on the static menu or on flyout menus. For more information, see How to: Customize the Display of Quick Launch.

Adding an Item Below a Built-In Heading

To insert a link below one of the standard Quick Launch headings, such as Lists or Libraries, call the AddToQuickLaunch method. This 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.

The AddToQuickLaunch method is in the SPNavigation class, an instance of which is returned by the Navigation property of the SPWeb class.

To add an item under a built-in heading

  1. (Optional) Check for an existing link to the same target by calling the GetNodeByUrl method of the object that is returned by the website's Navigation property.

    If the website's navigation structure does not include a link that points to the URL, the GetNodeByUrl method returns null.

  2. Create a node to represent the link by calling one of the constructors for the SPNavigationNode class.

    The class has two constructors:

    • The first constructor accepts two arguments: a string that contains display text for the link, and another string that contains the URL that the link should resolve. Use this constructor only for internal links—links to content in the same site collection. The URL should be server-relative.

    • The second constructor accepts three arguments. The first two arguments are the same as for the other constructor. The third argument is a boolean value that indicates whether the link is external or internal. Pass true for a link to an external website, and pass an absolute URL in the second argument. If the link is internal, pass false and a server-relative URL.

    Note

    An SPNavigationNode object is not completely initialized until it is added to a collection. If the object is not yet a member of a collection, read-only properties such as the Id property and the ParentId property return null.

  3. Call the AddToQuickLaunch method, passing the new node as the first argument and an SPQuickLaunchHeading enumeration value as the second argument.

    The AddToQuickLaunch method returns an initialized instance of the SPNavigationNode class. You can use this object to get and set other properties of the node. You must call the Update method after you change properties of the object.

Note

The quickest way to add an existing list or document library to the Quick Launch menu is to get an SPList object that represents the list or library, and then set the OnQuickLaunch property to true. An item for the list or library is automatically added below the appropriate heading. For information about Quick Launch headings, see the SPQuickLaunchHeading enumeration. If the heading does not yet appear on the Quick Launch menu, it is added.

Example

The following console application adds an item under the Lists heading in Quick Launch.

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

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SPSite site = new SPSite("https://localhost"))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    // Get the Links list or create it if it does not exist.
                    SPList list = web.Lists.TryGetList("Links");

                    if (list == null || list.BaseTemplate != SPListTemplateType.Links)
                    {
                        // Create the list.
                        Guid listId = web.Lists.Add("Links", "Interesting hyperlinks", SPListTemplateType.Links);
                        list = web.Lists.GetList(listId, false);
                    }

                    // Check for an existing link to the list.
                    SPNavigationNode listNode = web.Navigation.GetNodeByUrl(list.DefaultViewUrl);
 
                    // No link, so create one.
                    if (listNode == null)
                    {
                        // Create the node.
                        listNode = new SPNavigationNode(list.Title, list.DefaultViewUrl);

                        // Add it to Quick Launch.
                        listNode = web.Navigation.AddToQuickLaunch(listNode, SPQuickLaunchHeading.Lists);
                    }
                }
            }
            Console.Write("\nPress ENTER to continue....");
            Console.ReadLine();
        }
    }
}
Imports System
Imports Microsoft.SharePoint
Imports Microsoft.SharePoint.Navigation

Module ConsoleApp

    Sub Main()

        Using site As New SPSite("https://localhost")

            Using web As SPWeb = site.OpenWeb()

                ' Get the Links list or create it if it does not exist.
                Dim list As SPList = web.Lists.TryGetList("Links")

                If list Is Nothing OrElse list.BaseTemplate <> SPListTemplateType.Links Then

                    ' Create the list.
                    Dim listId As Guid = web.Lists.Add("Links", "Interesting hyperlinks", SPListTemplateType.Links)
                    list = web.Lists.GetList(listId, False)
                End If

                ' Check for an existing link to the list.
                Dim listNode As SPNavigationNode = web.Navigation.GetNodeByUrl(list.DefaultViewUrl)

                ' No link, so create one.
                If listNode Is Nothing Then

                    ' Create the node.
                    listNode = New SPNavigationNode(list.Title, list.DefaultViewUrl)

                    ' Add it to Quick Launch.
                    listNode = web.Navigation.AddToQuickLaunch(listNode, SPQuickLaunchHeading.Lists)
                End If

            End Using

        End Using

        Console.Write(vbCrLf & "Press ENTER to continue....")
        Console.Read()
    End Sub

End Module

Specifying a Position on the Menu

The AddToQuickLaunch method described in the previous section adds a new link as the last item below the specified heading on the Quick Launch menu. You can achieve more granular control over placement by using one of several methods in the SPNavigationNodeCollection class. The following table briefly describes these methods.

Method

Description

Add

Adds a new node after the specified node in the collection.

AddAsFirst

Adds a new node as the first node in the collection.

AddAsLast

Adds a new node as the last node in the collection.

The following procedure explains how to use the Add method to insert a link immediately after a specified item on the Quick Launch menu.

  1. Get the node for the heading under which you want to place the link by calling the GetNodeById method of the SPNavigation class.

    // Get the Libraries heading.
    SPNavigationNode heading = web.Navigation.GetNodeById((int)SPQuickLaunchHeading.Documents);
    
    ' Get the Libraries heading.
    Dim heading As SPNavigationNode = web.Navigation.GetNodeById(CInt(SPQuickLaunchHeading.Documents))
    
  2. Get the node for the item after which you want to place the link by querying the collection that is returned by the Children property of the heading node.

    // If a node for Shared Documents exists, the new node will go after it.
    SPList sharedDocs = web.Lists.TryGetList("Shared Documents");
    SPNavigationNode sharedDocsNode = null;
    if (sharedDocs != null)
        sharedDocsNode = librariesHeading
            .Children
            .Cast<SPNavigationNode>()
            .FirstOrDefault(n => n.Url == sharedDocs.DefaultViewUrl);
    
    ' If a node for Shared Documents exists, the new node will go after it.
    Dim sharedDocs As SPList = web.Lists.TryGetList("Shared Documents")
    Dim sharedDocsNode As SPNavigationNode = Nothing
    If sharedDocs IsNot Nothing Then
        sharedDocsNode = librariesHeading.Children.Cast(Of SPNavigationNode)().FirstOrDefault( _
            Function(n) n.Url = sharedDocs.DefaultViewUrl)
    End If
    
  3. Construct an SPNavigationNode object to represent the new link.

    SPNavigationNode newNode = new SPNavigationNode(list.Title, list.DefaultViewUrl);
    
    Dim newNode As SPNavigationNode = New SPNavigationNode(list.Title, list.DefaultViewUrl)
    
  4. Add the link by calling the Add method, passing the new node as the first argument and the node after which to add it as the second argument.

    newNode = heading.Children.Add(newNode, sharedDocsNode);
    
    newNode = heading.Children.Add(newNode, sharedDocsNode)
    

Note

An SPNavigationNode object is not completely initialized until it is added to a collection. If the object is not yet a member of a collection, read-only properties such as the Id property and the ParentId property return null.

Example

The following example shows how to add a link at a specific position on the Quick Launch menu. The example is part of a larger project that uses a web-scoped Feature to create a document library named Meeting Notes. The Feature includes an event handler that implements the SPFeatureReceiver class. In the FeatureActivated method of the feature receiver, there is code for creating the Meeting Notes library and adding a link to it under the Libraries heading. If the menu has a link to the Shared Documents library, the new link is inserted immediately after it. If the menu does not have a link to Shared Documents, the code makes the link to Meeting Notes the first item below the Libraries heading.

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 web = properties.Feature.Parent as SPWeb;
    if (web == null)
        return;

    // Get the Meeting Notes document library.
    SPList meetingNotes = web.Lists.TryGetList("Meeting Notes");
    if (meetingNotes == null)
    {
        // Create the library if it does not exist.
        Guid listId = web.Lists.Add("Meeting Notes", "An archive for meeting notes.", SPListTemplateType.DocumentLibrary);
        meetingNotes = web.Lists.GetList(listId, false);
    }

    // Check for an existing Quick Launch node for Meeting Notes.
    SPNavigationNode meetingNotesNode = web.Navigation.GetNodeByUrl(meetingNotes.DefaultViewUrl);

    // If a Meeting Notes node exists on Quick Launch, nothing more to do.
    if (meetingNotesNode != null)
        return;

    // Still here, so create a node for Meeting Notes.
    meetingNotesNode = new SPNavigationNode(meetingNotes.Title, meetingNotes.DefaultViewUrl);

    // Get the Libraries heading.
    SPNavigationNode librariesHeading = web.Navigation.GetNodeById((int)SPQuickLaunchHeading.Documents);

    // If the Libraries heading does not exist or it exists but has no items below it,
    // then Meeting Notes will be the first item.
    if (librariesHeading == null || librariesHeading.Children.Count == 0)
    {
        web.Navigation.AddToQuickLaunch(meetingNotesNode, SPQuickLaunchHeading.Documents);
        return;
    }

    // The Libraries heading exists. Now check for an item linking to Shared Documents.
    // If a node for Shared Documents exists, Meeting Notes will go after it.
    SPList sharedDocs = web.Lists.TryGetList("Shared Documents");
    SPNavigationNode sharedDocsNode = null;
    if (sharedDocs != null)
        sharedDocsNode = librariesHeading
            .Children
            .Cast<SPNavigationNode>()
            .FirstOrDefault(n => n.Url == sharedDocs.DefaultViewUrl);

    // A node for Shared Documents does not exist. Make Meeting Notes the first item.
    if (sharedDocsNode == null)
    {
        librariesHeading.Children.AddAsFirst(meetingNotesNode);
        return;
    }

    // A node for Shared Documents exists. Place Meeting Notes after it.
    librariesHeading.Children.Add(meetingNotesNode, sharedDocsNode);

    web.Dispose();
}
Public Overrides Sub FeatureActivated(ByVal properties As SPFeatureReceiverProperties)

    'Get the website where the feature is activated.
    Dim web As SPWeb = TryCast(properties.Feature.Parent, SPWeb)
    If web Is Nothing Then
        Return
    End If

    ' Get the Meeting Notes document library.
    Dim meetingNotes As SPList = web.Lists.TryGetList("Meeting Notes")
    If meetingNotes Is Nothing Then

        ' Create the library if it does not exist.
        Dim listId As Guid = web.Lists.Add("Meeting Notes", "An archive for meeting notes.", SPListTemplateType.DocumentLibrary)
        meetingNotes = web.Lists.GetList(listId, False)

    End If

    ' Check for an existing Quick Launch node for Meeting Notes.
    Dim meetingNotesNode As SPNavigationNode = web.Navigation.GetNodeByUrl(meetingNotes.DefaultViewUrl)

    ' If a Meeting Notes node exists on Quick Launch, nothing more to do.
    If meetingNotesNode IsNot Nothing Then
        Return
    End If

    ' Still here, so create a node for Meeting Notes.
    meetingNotesNode = New SPNavigationNode(meetingNotes.Title, meetingNotes.DefaultViewUrl)

    ' Get the Libraries heading.
    Dim librariesHeading As SPNavigationNode = web.Navigation.GetNodeById(CInt(SPQuickLaunchHeading.Documents))

    ' If the Libraries heading does not exist or it exists but has no items below it,
    ' then Meeting Notes will be the first item.
    If librariesHeading Is Nothing OrElse librariesHeading.Children.Count = 0 Then
        web.Navigation.AddToQuickLaunch(meetingNotesNode, SPQuickLaunchHeading.Documents)
        Return
    End If

    ' The Libraries heading exists. Now check for an item linking to Shared Documents.
    ' If a node for Shared Documents exists, Meeting Notes will go after it.
    Dim sharedDocs As SPList = web.Lists.TryGetList("Shared Documents")
    Dim sharedDocsNode As SPNavigationNode = Nothing
    If sharedDocs IsNot Nothing Then
        sharedDocsNode = librariesHeading.Children.Cast(Of SPNavigationNode)().FirstOrDefault( _
            Function(n) n.Url = sharedDocs.DefaultViewUrl)
    End If

    ' A node for Shared Documents does not exist. Make Meeting Notes the first item.
    If sharedDocsNode Is Nothing Then
        librariesHeading.Children.AddAsFirst(meetingNotesNode)
        Return
    End If

    ' A node for Shared Documents exists. Place Meeting Notes after it.
    librariesHeading.Children.Add(meetingNotesNode, sharedDocsNode)

    web.Dispose()
End Sub

Adding a Custom Heading

The headings on the Quick Launch menu are SPNavigationNode objects. The collection of all headings is returned by the QuickLaunch property of the Navigation object of the website. You can add a custom heading by constructing a new navigation node and adding it to the collection by calling a method of the SPNavigationNodeCollection class, such as the AddAsLast method.

To add a custom heading to Quick Launch

  1. Construct an SPNavigationNode object to represent the navigation node for the new heading.

    string headingTitle = "Resources";
    string headingUrl = web.Navigation.Home.Url;
    SPNavigationNode heading = new SPNavigationNode(headingTitle, headingUrl);
    
    Dim headingTitle As String = "Resources"
    Dim headingUrl As String = web.Navigation.Home.Url
    Dim heading As SPNavigationNode = New SPNavigationNode(headingTitle, headingUrl)
    
  2. Get the collection of navigation nodes that is returned by the QuickLaunch property of the object that is returned by the SPWeb.Navigation property of the website.

    SPNavigationNodeCollection quickLaunch = web.Navigation.QuickLaunch;
    
    Dim quickLaunch As SPNavigationNodeCollection = web.Navigation.QuickLaunch
    
  3. Add the new heading node to the collection by calling a method of the SPNavigationNodeCollection class.

    heading = quickLaunch.AddAsLast(heading);
    
    heading = quickLaunch.AddAsLast(heading)
    

    The example calls the AddAsLast method. Two other methods are available: the AddAsFirst method and the Add method.

  4. (Optional) Add items below the new heading by getting the collection that is returned by the Children property of the new heading and again calling a method of the SPNavigationNodeCollection class.

    SPNavigationNode item = new SPNavigationNode(itemTitle, itemUrl);
    item = heading.Children.AddAsLast(item);
    
    Dim item As SPNavigationNode = New SPNavigationNode(itemTitle, itemUrl)
    item = heading.Children.AddAsLast(item)
    

Example

The following example is a console application that creates a new Quick Launch menu heading for Resources and adds an item below the new heading.

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("https://localhost"))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    string headingTitle = "Resources";
                    string headingUrl = web.Navigation.Home.Url;
                    string itemTitle = "SharePoint Developer Center";
                    string itemUrl = "https://msdn.microsoft.com/sharepoint";

                    // Get the Quick Launch headings.
                    SPNavigationNodeCollection ql = web.Navigation.QuickLaunch;

                    // If a Resources heading exists, get it.
                    SPNavigationNode heading = ql
                        .Cast<SPNavigationNode>()
                        .FirstOrDefault(n => n.Title == headingTitle);

                    // If the Resources heading does not exist, create it.
                    if (heading == null)
                    {
                        heading = new SPNavigationNode(headingTitle, headingUrl);
                        heading = ql.AddAsLast(heading);
                    }

                    // If the heading has a SharePoint Dev Center item, get it.
                    SPNavigationNode item = heading
                        .Children
                        .Cast<SPNavigationNode>()
                        .FirstOrDefault(n => n.Url == itemUrl);

                    // If the item does not exist, create it.
                    if (item == null)
                    {
                        item = new SPNavigationNode(itemTitle, itemUrl, true);
                        item = heading.Children.AddAsLast(item);
                    }
                 }
            }
            Console.Write("\nPress ENTER to continue....");
            Console.ReadLine();
        }
    }
}
Imports System
Imports Microsoft.SharePoint
Imports Microsoft.SharePoint.Navigation

Module ConsoleApp

    Sub Main()

        Using site As New SPSite("https://localhost")
            Using web As SPWeb = site.OpenWeb()

                Dim headingTitle As String = "Resources"
                Dim headingUrl As String = web.Navigation.Home.Url
                Dim itemTitle As String = "SharePoint Developer Center"
                Dim itemUrl As String = "https://msdn.microsoft.com/sharepoint"

                ' Get the Quick Launch headings.
                Dim ql As SPNavigationNodeCollection = web.Navigation.QuickLaunch

                ' If a Resources heading exists, get it.
                Dim heading As SPNavigationNode = ql.Cast(Of SPNavigationNode)().FirstOrDefault( _
                    Function(n) n.Title = headingTitle)

                ' If the Resources heading does not exist, create it.
                If heading Is Nothing Then
                    heading = New SPNavigationNode(headingTitle, headingUrl)
                    heading = ql.AddAsLast(heading)
                End If

                ' If the heading has a SharePoint Dev Center item, get it.
                Dim item As SPNavigationNode = heading.Children.Cast(Of SPNavigationNode)().FirstOrDefault( _
                    Function(n) n.Url = itemUrl)

                ' If the item does not exist, create it.
                If item Is Nothing Then
                    item = New SPNavigationNode(itemTitle, itemUrl, True)
                    item = heading.Children.AddAsLast(item)
                End If

            End Using
        End Using

        Console.Write(vbCrLf & "Press ENTER to continue....")
        Console.Read()
    End Sub

End Module

See Also

Tasks

How to: Display or Hide Quick Launch

How to: Customize the Display of Quick Launch

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