Click here to Skip to main content
Email Password   helpLost your password?

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.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralI found the staticsitemapprovider to be the easiest solution to making custom provider
qwertyuuuu
20:34 3 Aug '09  
There is working (!) example at:

http://msdn.microsoft.com/en-us/library/system.web.staticsitemapprovider.aspx[^]
QuestionCan i use this to modify colors?
StarChildDK
0:08 7 Mar '09  
Hi im looking for a way to set different colors for each sub menu, and different colors for each top menu item.. is that posible?
AnswerRe: Can i use this to modify colors?
feelite
0:15 7 Mar '09  
that's possible, you can set fine-grained styles by using the various properties of the MenuItem object.

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.menuitem.aspx[^]
GeneralRe: Can i use this to modify colors?
StarChildDK
1:07 7 Mar '09  
Yes but thats still on a static "homemade" menu, i need it to be done on a menu with DataSourceID="SiteMapDataSource1".
Picture yourself a menu with links to 3 sites: cars boats airplanes

And every link have 3 under links, lets call them: one, two, three.

I need the cars link to have blue background
And all the sublinks need to have blue letters.

I need the boats link to have green background
And all the sublinks need to have green letters.

I need the airplanes link to have yellow background
And all the sublinks need to have yellow letters.

How do i do that?

Kind regards
Morten
GeneralRe: Can i use this to modify colors?
Jiang Qiu
8:39 8 Mar '09  
i can't say for certain at this point but http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.menu.levelmenuitemstyles.aspx[^] or http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.menu.dynamicitemtemplate.aspx[^] may meet your requirement.
GeneralHow about performance?
Koen Zomers
23:31 22 Oct '08  
Thank you for this article.

Did you do performance testing on this code? To me it sounds like a performance issue to read the XML file with each request and build up the whole menu again. Wouldn't it be more efficient to apply some kind of caching on the menu?
GeneralRe: How about performance?
feelite
1:34 24 Oct '08  
I agree. Since the XML file won't change most of the time, it's better to have it cached to avoid IO operations. Thanks for your suggestion.
Generaladd different color menu tab in MOSS
tanu123
3:06 28 May '08  
I want to customize the color of each item in the menu(globalnav) in MOSS.How to do that
GeneralRe: add different color menu tab in MOSS
feelite
1:39 24 Oct '08  
if you're talking about customizing the built-in site map providers in SP, you need to override the relevant styles such as ms-topnavContainer and ms-topnavselected classes.

Refer to http://www.heathersolomon.com/content/sp07cssreference.htm[^] for more info.
GeneralRequired
Programm3r
23:52 12 May '08  
Hi,

Just something I want to mention, please correct the image link and the general formatting of the code snippets.

Thanks

Regards,


The only programmers that are better that C programmers are those who code in 1's and 0's Green Alien
Smile Programm3r My Blog: ^_^

GeneralRe: Required
feelite
23:54 12 May '08  
thanks for pointing that out. I've attached the screen shot together with the submission and waiting for the link to be updated when they approve the article.
GeneralRe: Required
Mark Nischalke
3:05 13 May '08  
feelite wrote:
waiting for the link to be updated when they approve the article

You're in a Catch22, it's not getting approved until you make the corrections. Image links are not dependent on article approval.


only two letters away from being an asset

GeneralRe: Required
feelite
3:31 13 May '08  
i fixed the links and cleaned some typos etc. Smile


Last Updated 13 May 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010