Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / productivity / SharePoint / SharePoint2010

How to Create Custom Top & Left in SharePoint 2010

4.50/5 (2 votes)
2 Dec 2014CPOL5 min read 19.9K   119  
How to create a custom top and left in SharePoint 2010

Introduction

Every SharePoint version comes with OOB navigation feature, which is quite useful. You can quickly create a site navigation, provide some audience and there you go, your site navigation is set.

Suppose you have some very strange business requirement, where the OOB navigation does not serve the purpose and you are being asked to customize it for the sake of Business requirement, now that would be a challenge for some people.

In one of my projects, there was a very complex requirement. We had to manipulate the Top and Left navigation based on some kind of impersonation. For example, When User A logs in, this user will have the ability to impersonate into another user account. The whole Top and Left navigation would behave as if the actual user has logged in who has been impersonated by user A.

User A logs in and the following screen appears from where they can click on account and can impersonate as if that account is logging in to the portal.

Image 1

After impersonation, the custom code kicks in and loads the navigation like following. Both are different on the basis of which account was clicked from Gridview above. And also, the sub items under each menu will be different based on which one is clicked.

Image 2

Image 3

We tried achieving this through manipulating the OOB navigation through Audiences and Groups but that did not achieve the desired result and many bugs were reported. Normal User OOB navigation would work fine, but the impersonated one was not.

The only possible solution to this complex business requirement was to write the whole Top and Left navigation from start and code it based on the business requirement.

So here we go!

Sharepoint Content Types and List

First step towards building up custom site navigation is to have a Navigation data source. We have different options for this. I went with a SharePoint Custom List. The reason I chose a Custom List is simple. Our business requirement was to have a Parent Navigation and sub items underneath it with one Level.

Content Type

Create the following content types:

  • Folder Content Type to Create Folders which will represent the Parent Navigation Items:

    Name Type Status Source
    Nav Item URL Hyperlink or Picture Optional Custom Navigation Folder
    Nav Link Item Audience Person or Group Optional Custom Navigation Folder
    Nav Link Item Order Number Required Custom Navigation Folder
    Nav Link Item Open New window Choice Optional Custom Navigation Folder
    Title Single line of text Hidden Item
  • Item Content Type to Create Sub Items which will represent the child Navigation Items:

    Title Single line of text Required Item
    Nav Item URL Hyperlink or Picture Optional Custom Navigation Items
    Nav Link Item Audience Person or Group Optional Custom Navigation Items
    Nav Link Item Open New window Choice Optional Custom Navigation Items
    Nav Link Item Order Number Required Custom Navigation Items

SharePoint LIST

Create a Sharepoint list based on the above content type and add the data.

Top navigation is represented by Folder Content Type.

Image 4

Children are created using Item Content Type.

Image 5

Example of an item created:

Image 6

Using the Code

The whole idea of creating this article is to create a simple project which would demonstrate how to create a SharePoint custom navigation based on the Custom List above. I would not delve down about the details of how I achieved the end result of our business require, but I will show how to create the custom navigation and then once you know the basics, you can manipulate the code to achieve the desired result.

  1. The first step is to create an Interface to represent the navigation nodes. The same interface will be used to represent Top and Left navigation items.
    C#
    public interface INavigationItem
        {
            #region PROPERTIES
            /// <summary>
            ///
            /// </summary>
            string Title { get; set; }
            /// <summary>
            ///
            /// </summary>
            string Url { get; set; }
            /// <summary>
            ///
            /// </summary>
            string Audience { get; set; }
            /// <summary>
            ///
            /// </summary>
            int Order { get; set; }
            /// <summary>
            ///
            /// </summary>
            int Id { get; set; }
            /// <summary>
            ///
            /// </summary>
            bool IsOpenInNewWindow { get; set; }
            #endregion
            #region METHODS
            /// <summary>
            /// Get the parent navigation Items
            /// </summary>
            /// <param name="_TopNavList"></param>
            /// <param name="_Folder"></param>
            Dictionary<INavigationItem, int> 
            GetParentNavItems(SPList _TopNavList, SPFolder _Folder);
            /// <summary>
            /// Get the parent navigation Items
            /// </summary>
            /// <param name="sParentNavTitle"></param>
            /// <returns></returns>
            INavigationItem GetParentNavItem(string sParentNavTitle);
            /// <summary>
            /// Get child navigation Items
            /// </summary>
            /// <param name="_TopNavList"></param>
            /// <param name="_Folder"></param>
            /// <param name="iParentFolderID"></param>
            Dictionary<INavigationItem, int> GetChildNavItems
            (SPList _TopNavList, SPFolder _Folder, int iParentFolderID);
            /// <summary>
            /// Get child navigation Items
            /// </summary>
            /// <param name="_TopNavList"></param>
            /// <param name="_Folder"></param>
            /// <param name="iParentFolderID"></param>
            Dictionary<INavigationItem, int> 
            GetChildNavItems(SPList _TopNavList, SPFolder _Folder);
            /// <summary>
            /// Populate the navigation items
            /// </summary>
            /// <param name="_TopNavList"></param>
            /// <param name="_StartingFolder"></param>
            /// <param name="psmNode"></param>
            SiteMapNodeCollection PopluateNavigationItems
            (SPList _TopNavList, SPFolder _StartingFolder, PortalSiteMapNode psmNode);
            #endregion
        }
  2. A SharePoint Solution will be created to code the Navigation solution. Sharepoint PortalSiteMapProvider is the class to use represent the nodes. This class inherits the Sitemapnode class. The difference between a SiteMapNode and a PortalSiteMapNode, is that the PortalSiteMapNode uses MOSS security trimming. This is a good thing. Use it. However, there isn’t a PortalSiteMapNodeCollection class in Sharepoint. You still use a SiteMapNodeCollection to add and delete nodes.
    C#
    public class TopNavigationProvider : PortalSiteMapProvider
    {
    
    }
    
    public class LeftNavigationProvider : PortalSiteMapProvider
    {
    
    }

    This class has GetChildNodes method of PortalSiteMapnode class is the method to create nodes. This method has various override signatures and can be used as per requirement. I am using the following method, node object shall be boxed to PortalSiteMapNode to get the Sharepoint node.

    C#
      /// <summary>
      ///
     /// </summary>
    private SiteMapNodeCollection GetChildNodes(SiteMapNode node)
    {
       PortalSiteMapNode pNode = node as PortalSiteMapNode;
       //……………………………………
    }
  3. Then another class is being used to set up the whole navigation (both TOP and Left) which will be inherited from our Interface to set up Top and Left navigation. These classes will be used inside provider classes GetChildNodes method to create navigation.
    C#
    /// <summary>
       /// This class represents an Navigation Item
       /// </summary>
       public class TopNavigationItem : INavigationItem
       {
       }
    
    /// <summary>
       /// This class represents an Navigation Item
       /// </summary>
       public class LeftNavigationItem : INavigationItem
       {
       }
    
  4. The next step is to set up the Web.config. Add the following keys to sitemap section in the Web.config. Here, TopNavigationProvider is the name of the class which has the logic for Top navigation.
    XML
    <siteMap defaultProvider="CurrentNavigation" enabled="true">
          <providers>
            <add name="TopNavigationProvider" type="XYZ.Navigation.TopNavigationProvider,
            XYZ.Navigation, Version=1.0.0.0, Culture=neutral,
            PublicKeyToken=a1a91a3" NavigationType="Global" />
            <add name="LeftNavigationProvider" type="XYZ.Navigation.LeftNavigationProvider,
            XYZ.Navigation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a1a91a32d"
            NavigationType="Global" />
  5. The next step is to set up the Master page. Inside site master page, there are two sections which represent the Top navigation and Left navigation providers. We will override out of the box providers will use our custom providers. It is never wise to play with Master pages directly. So please make all the changes using the SharePoint Designer. Edit the master page which your site is using and replace the following section to use our custom providers. replace the <asp:ContentPlaceHolder id="PlaceHolderTopNavBar" runat="server"> in master page with the following for Top Navigation Bar. Use the exact SiteMapProvider name for Top Navigation from your web.config entries.
    ASP.NET
    <asp:ContentPlaceHolder id="PlaceHolderTopNavBar" runat="server">
                                <h2 class="ms-hidden">
                                <SharePoint:EncodedLiteral runat="server"
                                text="<%$Resources:wss,topnav_pagetitle%>"
                                EncodeMethod="HtmlEncode"/></h2>
                                        <asp:ContentPlaceHolder id="PlaceHolderHorizontalNav"
                                        runat="server">
                                    <SharePoint:AspMenu
                                      ID="TopNavigationMenuV4"
                                      Runat="server"
                                      EnableViewState="true"
                                      DataSourceID="topSiteMap"
                                      AccessKey="<%$Resources:wss,navigation_accesskey%>"
                                      UseSimpleRendering="true"
                                      UseSeparateCss="false"
                                      Orientation="Horizontal"
                                      StaticDisplayLevels="1"
                                      MaximumDynamicDisplayLevels="3"
                                      SkipLinkText=""
                                      CssClass="s4-tn"/>
                                        <asp:SiteMapDataSource
                                                      SiteMapProvider="TopNavigationProvider"
                                                      StartFromCurrentNode="true"
                                                      StartingNodeOffset="0"
                                                      ShowStartingNode="false"
                                                      EnableViewState="true"
                                                      id="topSiteMap"
                                                      runat="server"
                                                  />
                                        </asp:ContentPlaceHolder>
                                </asp:ContentPlaceHolder>
  6. Replace the <asp:ContentPlaceHolder id="PlaceHolderLeftNavBar" runat="server"> in master page with the following for left Navigation Bar. Use the exact SiteMapProvider name for Left Navigation from your web.config entry.
    ASP.NET
    <asp:ContentPlaceHolder id="PlaceHolderLeftNavBar" runat="server">
                                <SharePoint:AspMenu
                                ID="CurrentNav"
                                EncodeTitle="false"
                                runat="server"
                                EnableViewState="false"
                                DataSourceID="ContentSiteMap"
                                UseSeparateCSS="false"
                                UseSimpleRendering="true"
                                Orientation="Vertical"
                                StaticDisplayLevels="2"
                                MaximumDynamicDisplayLevels="0"
                                CssClass="s4-ql"
                                SkipLinkText="<%$Resources:cms,masterpages_skiplinktext%>"/>
                                <asp:SiteMapDataSource
                                    SiteMapProvider="LeftNavigationProvider"
                                    ShowStartingNode="False"
                                    id="ContentSiteMap"
                                    runat="server"
                                    />
                        </asp:ContentPlaceHolder>
  7. Upload the master page and deploy the WSP and you should have custom navigation being driven from SharePoint list.

Conclusion

So, we saw how we can override the OOB navigation using some of the above steps. Attached is the code which you can download and create a basic solution to set up the custom navigation. I hope this helps.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)