5,550,131 members and growing! (18,894 online)
Email Password   helpLost your password?
Enterprise Systems » SharePoint Server » General     Intermediate License: The BSD License

SharePoint Custom Site Navigation

By feelite

This articles provides an overview on how to do customized site navigation on MOSS publishing sites.
VB (VB 9.0, VB), CSS, HTML, XHTML, Windows (Windows, Win2003), .NET (.NET, .NET 3.5), ASP, ASP.NET, Ajax, Dev

Posted: 12 May 2008
Updated: 12 May 2008
Views: 8,795
Bookmarked: 13 times
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
2 votes for this Article.
Popularity: 0.90 Rating: 3.00 out of 5
0 votes, 0.0%
1
0 votes, 0.0%
2
2 votes, 100.0%
3
0 votes, 0.0%
4
0 votes, 0.0%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

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

About the Author

feelite


Glenn is a technical consultant who helps solve clients’ business problems through technology. Grounded in the solid fundamentals of programming skills, he keeps abreast of the latest trends (e.g. REST, JSON and RIA) in the software development world so as to make the best decision among alternatives in the design and implementation of requirements.
Occupation: Team Leader
Company: Avanade
Location: United Kingdom United Kingdom

Other popular SharePoint Server articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 5 of 5 (Total in Forum: 5) (Refresh)FirstPrevNext
Subject  Author Date 
Generaladd different color menu tab in MOSSmembertanu1233:06 28 May '08  
GeneralRequiredmember Programm3r 23:52 12 May '08  
GeneralRe: Requiredmemberfeelite23:54 12 May '08  
GeneralRe: RequiredsupporterMark Nischalke3:05 13 May '08  
GeneralRe: Requiredmemberfeelite3:31 13 May '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 12 May 2008
Editor: Sean Ewington
Copyright 2008 by feelite
Everything else Copyright © CodeProject, 1999-2008
Web09 | Advertise on the Code Project