Click here to Skip to main content
Click here to Skip to main content

SharePoint Custom Site Navigation

, 12 May 2008
Rate this:
Please Sign up or sign in to vote.
This articles provides an overview on how to do customized site navigation on MOSS publishing sites.

screen.png

Introduction

This articles provides an overview on how to do customized site navigation on MOSS publishing sites. If you are wondering whether that is configurable using the Site Settings page, read on.

Background

SharePoint 2007 comes with web content management features and its own custom SiteMapProvider. Out of the box, any sites and sub-sites created under a publishing site will have its URL nailed tp the top navigation menu. While this is desirable in a typical WCM environment and is certainly configurable from the built-in Site Settings functionality, when used in a non-WCM environment, it can be problematic.

Suppose you want a fixed top navigation menu that is not associated to your site topology, then the out of the box provider cannot be used.

You may ask why I would use the publishing site in the first place. Well, most of the SharePoint custom site definitions require you to use a definition that's based from the publishing one. In order to get user-swappable master pages and alternate CSS files, you have to start with the publishing site.

By default, the following section exists in the web.config file for a publishing site. As you can see, CurrentNavSiteMapProvider defines the provider used in a Publishing site.

<siteMap defaultProvider="CurrentNavSiteMapProvider" enabled="true">
      <providers>
        <add name="SPNavigationProvider" type="Microsoft.SharePoint.Navigation.SPNavigationProvider, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="SPSiteMapProvider" type="Microsoft.SharePoint.Navigation.SPSiteMapProvider, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="SPContentMapProvider" type="Microsoft.SharePoint.Navigation.SPContentMapProvider, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="SPXmlContentMapProvider" siteMapFile="_app_bin/layouts.sitemap" type="Microsoft.SharePoint.Navigation.SPXmlContentMapProvider, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="AdministrationQuickLaunchProvider" description="QuickLaunch navigation provider for the central administration site" type="Microsoft.Office.Server.Web.AdministrationQuickLaunchProvider, Microsoft.Office.Server.UI, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="SharedServicesQuickLaunchProvider" description="QuickLaunch navigation provider for shared services administration sites" type="Microsoft.Office.Server.Web.SharedServicesQuickLaunchProvider, Microsoft.Office.Server.UI, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="GlobalNavSiteMapProvider" description="CMS provider for Global navigation" type="Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" NavigationType="Global" EncodeOutput="true" IncludePages="PerWeb" IncludeHeadings="true" IncludeAuthoredLinks="true" />
        <add name="CombinedNavSiteMapProvider" description="CMS provider for Combined navigation" type="Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" NavigationType="Combined" EncodeOutput="true" IncludePages="PerWeb" IncludeHeadings="true" IncludeAuthoredLinks="true" />
        <add name="CurrentNavSiteMapProvider" description="CMS provider for Current navigation" type="Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral,PublicKeyToken=71e9bce111e9429c" NavigationType="Current" EncodeOutput="true" IncludePages="PerWeb" IncludeHeadings="true" IncludeAuthoredLinks="true" />
        <add name="CurrentNavSiteMapProviderNoEncode" description="CMS provider for Current navigation, no encoding of output" type="Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" NavigationType="Current" EncodeOutput="false" IncludePages="PerWeb" IncludeHeadings="true" IncludeAuthoredLinks="true" />
        <add name="SiteDirectoryCategoryProvider" description="Site Directory category provider" type="Microsoft.SharePoint.Portal.WebControls.SiteDirectoryCategoryProvider, Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="MySiteMapProvider" description="MySite provider that returns areas and based on the current user context" type="Microsoft.SharePoint.Portal.MySiteMapProvider, Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="MySiteLeftNavProvider" description="MySite Left Nav provider that returns areas and based on the current user context" type="Microsoft.SharePoint.Portal.MySiteLeftNavProvider,  Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="UsagePagesSiteMapProvider" description="Provider for navigation in Portal Usage pages" type="Microsoft.SharePoint.Portal.Analytics.UsagePagesSiteMapProvider, Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="SPXmlAdminContentMapProvider" siteMapFile="_app_bin/admin.sitemap" type="Microsoft.SharePoint.Navigation.SPXmlContentMapProvider, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      </providers>
 </siteMap>

 

Correspondingly, the actual control that spits out navigation control is placed in the master page as follows. This is the custom control that provides the ability to show/hide sub-sites and etc in the SharePoint Site Settings page.

<publishingnavigation:portalsitemapdatasource id="SiteMapDataSourceRoot" runat="server" 
   sitemapprovider="CombinedNavSiteMapProvider" enableviewstate="true" 
   startfromcurrentnode="true" startingnodeoffset="0" showstartingnode="true">
</publishingnavigation:portalsitemapdatasource>

To override this behavior, you will need to do a few things.

  1. Create a new master page based on the BlackBand.master (or any master page in the directory under the PublishingLayouts feature).
  2. Replace the PublishingNavigation control declaration with a menu control.
  3. Create the code-behind file for the master page to load the custom navigation.
  4. Add the code-behind information to the master page directive and deploy the new master page to SharePoint plus the assemblies.
 Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
            MyBase.OnLoad(e)
            Dim menu As Menu = DirectCast(FindControl("Menu1"), Menu)

            Dim doc As XDocument = XDocument.Load(
                "C:\Inetpub\wwwroot\wss\VirtualDirectories\80\web.sitemap")
            Dim query = From c In doc.Element("menuitems").Elements("menuitem")

            Dim parentItem As MenuItem
            For Each element As XElement In query
                parentItem = New MenuItem()

                Dim subQuery = From c In element.Elements("menuitem")
                For Each node As XElement In subQuery
                    Dim item As New MenuItem()
                    With item
                        .Text = node.Attribute("text")
                        .NavigateUrl = node.Attribute("navigateurl")
                        .ToolTip = node.Attribute("tooltip")
                        .ImageUrl = "tool.png"
                    End With
                    parentItem.ChildItems.Add(item)

                Next

                With parentItem
                    .Text = element.Attribute("text")
                    .NavigateUrl = element.Attribute("navigateurl")
                    .ToolTip = element.Attribute("tooltip")
                    .ImageUrl = "heart.png"
                End With
                menu.Items.Add(parentItem)
            Next
 End Sub

Essentially, the code-behind will load an XML file called web.sitemap (it can be any XML file you prefer) and iteratively add navigation nodes to the menu. This way, you can even add personalized nodes to the navigation as needed.

Points of Interest

Why using a Publishing Site?

Well, most of the SharePoint custom site definitions require you to use a definition that's based from the publishing one. In order to get user-swappable master pages and alternate CSS files, you have to start with the publishing site.

Why not XmlSiteMapProvider?

If you use that provider (out of the box from ASP.NET 2.0), you will not be able to modify the nodes in the navigation. The Items property of this object will have zero items for you to modify.

Why LINQ to XML?

Of course, using LINQ to XML is not needed. It merely simplifies hard-to-decipher nested loops or XPath that usually comes with XML document processing.

History

[May 14, 2008] Added a short FAQ section.

License

This article, along with any associated source code and files, is licensed under The BSD License

Share

About the Author

Jiang Qiu
Team Leader Avanade
United Kingdom United Kingdom
Thoroughly convinced by the simplicity of C# and the richness of the base class library, Jiang moved from Java/C++ to the Microsoft .NET platform after having completed his computer science degree. A few years into your run-of-the-mill business reporting projects, he discovered the fun of working with SharePoint and has since been more and more enamored with the breadth of the product. Sadly to say, not all projects involve heroic debugging sessions with parallel and concurrent programming and sometimes SharePoint designer is all he gets to plays with.

Comments and Discussions

 
QuestionHow about performance? PinmemberKoen Zomers22-Oct-08 22:31 
AnswerRe: How about performance? Pinmemberfeelite24-Oct-08 0:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140826.1 | Last Updated 13 May 2008
Article Copyright 2008 by Jiang Qiu
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid