Managed Metadata Navigation for Multiple Site Collections in SharePoint 2013

Managed metadata navigation is a new feature in SharePoint 2013 that allows the user to configure the navigation on a site collection based on a term set in the term store. This brings a lot of benefits for the site administrators, as they can define SEO-friendly URL’s, and they can update the navigation anytime using the term store management tool. There are several blog posts out there that show how it can be configured, so I will skip this part.

Although it is a very powerful feature, it still has some limitations. They can be seen especially when you have an Information Architecture that spans across a lot of site collections and maybe across web applications, and you would like to use the same navigation in all places. When you try to bind the same navigation term set to a new site, you will get a message that says the term set is already bound to a different site, and if you choose to proceed, the navigation settings for the other site will be broken.

message_attaching

Considering you have proceeded, on the initial site, the navigation will not work anymore, and you will receive an error message.

error_message_navigation

I have searched for different resolutions on this topic and  I have found two solutions on how to overcome it:

  • Create a new term set, and pin it to the source term set. The new term set is a copy of the source term set, and it can be used in a new site collection. This technique is explained in more detail here. However, if you have a lot of site collections, this can lead to a very large number of term groups and term sets in the term store.
  • Create a custom control (server-side), or a script (client-side JavaScript) that reads from a term set in the term store, and renders the navigation as you want it. You can find a sample for this here, and it also includes source code and explanation for it. if you are using this, you will have to recreate the Html and JavaScript for the navigation, that is by default rendered by the AspMenu control (this might become tricky if there are multiple dynamic levels for the navigation).

Another solution would be to create a custom navigation provider that retrieves the navigation nodes from a managed metadata navigation term set. I find this solution an easy way to overcome the limitation because you only have to retrieve the navigation nodes, and you can leave the rendering to the default AspMenu control. It is a highly reusable solution, which requires no change when it is used in different projects for different customers. The drawback – you need a farm solution to be able to create a custom navigation provider.

I will not post the entire code for this here, but I will only highlight the main ideas that are needed for this:

  •  Create the custom navigation provider. You will have to create a class that inherits from PortalSiteMapProvider or from SiteMapProvider. Code sample for this can be found on msdn.
  • Register the navigation provider with a web application feature, and by making changes to web.config file. Code sample for this can be found on msdn.
  • Change the master page to use your navigation control, or deploy an elements file with a control element that enables the use of your navigation provider. Code sample for this can be found on msdn.
  • I recommend using the cache for the navigation data, once you retrieve it from the term store. You can use the web application cache, or the distributed cache service. I prefer the later one, as  it works the same way across multiple front-ends.
  • When you retrieve the data from the navigation term set, the key method is NavigationTermSet.GetAsResolvedByWeb , as it returns the navigation term set object, as if it would be attached to that web.
  • Once you have the NavigationTermSet object, you can find all its children NavigationTerm . From there, you can work with everything that you can define in the term store management tool for that term.

I would have liked SharePoint 2013 to ship with such a navigation provider OOB, but, if not, the effort to implement it is not really large, and I believe it is definitely worth it.

Advertisements
3 comments
  1. Bogdan said:

    Hi – excellent post. Do you mind sharing the complete class? From what I understand you have to override GetChildNodes. That method returns SiteMapNodeCollection. How do you convert NavigationTermSet to SiteMapNodeCollection as one object without building the entire tree as a SiteMapNodeCollection?

    Or how to take the NavigationTermSet and serve it to your provider as its datasource?

    Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: