Click here to Skip to main content
15,867,749 members
Articles / Web Development / XHTML
Article

SharePoint Custom Site Navigation

Rate me:
Please Sign up or sign in to vote.
3.00/5 (2 votes)
12 May 2008BSD2 min read 132.3K   393   32   14
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.

XML
<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.

XML
<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.
VB
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


Written By
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

 
GeneralThere's a great solution that based on the same Idea Pin
bob.cedric15-Jun-10 8:37
bob.cedric15-Jun-10 8:37 
GeneralI found the staticsitemapprovider to be the easiest solution to making custom provider Pin
qwertyuuuu3-Aug-09 19:34
qwertyuuuu3-Aug-09 19:34 
QuestionCan i use this to modify colors? Pin
StarChildDK6-Mar-09 23:08
StarChildDK6-Mar-09 23:08 
AnswerRe: Can i use this to modify colors? Pin
Jiang Qiu6-Mar-09 23:15
Jiang Qiu6-Mar-09 23:15 
GeneralRe: Can i use this to modify colors? Pin
StarChildDK7-Mar-09 0:07
StarChildDK7-Mar-09 0:07 
GeneralRe: Can i use this to modify colors? Pin
Jiang Qiu8-Mar-09 7:39
Jiang Qiu8-Mar-09 7:39 
QuestionHow about performance? Pin
Koen Zomers22-Oct-08 22:31
Koen Zomers22-Oct-08 22:31 
AnswerRe: How about performance? Pin
Jiang Qiu24-Oct-08 0:34
Jiang Qiu24-Oct-08 0:34 
Generaladd different color menu tab in MOSS Pin
tanu12328-May-08 2:06
tanu12328-May-08 2:06 
GeneralRe: add different color menu tab in MOSS Pin
Jiang Qiu24-Oct-08 0:39
Jiang Qiu24-Oct-08 0:39 
GeneralRequired Pin
Programm3r12-May-08 22:52
Programm3r12-May-08 22:52 
GeneralRe: Required Pin
Jiang Qiu12-May-08 22:54
Jiang Qiu12-May-08 22:54 
GeneralRe: Required Pin
Not Active13-May-08 2:05
mentorNot Active13-May-08 2:05 
GeneralRe: Required Pin
Jiang Qiu13-May-08 2:31
Jiang Qiu13-May-08 2:31 

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

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