Skip to main content

Cloud

SharePoint 2013 Managed Navigation: Pros, Cons, and Code

I recently posted a script to export term sets in SharePoint (vetted in both 2010 & 2013).  I was prompted to write that script, because the client I was working on had a very particular (and large!) managed navigation structure that I wanted to replicate across all environments to make testing code much simpler. This was my first experience using 2013’s managed navigation and I wanted to share my thoughts and see if anyone else has had similar/different experiences with it so far.
For those of you that don’t know, managed navigation is new in SharePoint 2013.  It gives you the option to base the navigation on taxonomy rather than “physical” structure.  It uses a dedicated term set for site navigation and the terms correspond to the friendly URL segment created. 
For instance, http://site.com/example/of/managed/navigation would correspond to the following term hierarchy:

example (root term) –> of –> managed –> navigation

And the term ‘navigation’ would be mapped to the physical URL (the /Pages/page.aspx URL) of the specific page you want shown when a user navigates to that URL.
Managed navigation provides a lot of flexibility for how you want your site organized and optimizes your URLs for SEO.  It makes it possible to move pages across “sites” or locations (if you think of a site in terms of what an end user sees rather than the SharePoint structure for site) without actually moving or touching the physical page.
In my experience, managed navigation is great in certain scenarios and in other instances may not be the best choice.  I’ve briefly outlined the pros and cons that I’ve experienced personally.
Pros

  • User Experience: Managed navigation gives your site a consistent, easy URL schema for your end users.  I don’t know about you, but not seeing http://site.com/Pages/AboutUs.aspx and seeing http://site.com/about-us instead just seems so much cleaner and more intuitive, especially as the logical organization gets deeper.
  • New customization opportunities: Who doesn’t love shiny new toys?? Because the navigation is now taxonomy driven, custom navigation controls are easier to code and maintain (in my opinion) and provide more flexibility.  Navigation terms come with a lot of properties OOTB, but you can also define your own custom properties programmatically or through the UI to use in your custom controls.

Cons

  • Content authoring: In order to reap the full benefits of SEO optimized friendly URLs, you have to set the “Hide physical URL from search” property to true on every page otherwise search indexes the physical URL and you lose the benefits of the friendly URLs (especially if you have custom controls appearing on friendly URL pages which won’t appear on physical pages).  However, this means that the physical pages are also hidden from search/within the document libraries.  Even though this seems small, if you are a content author sifting through hundreds of pages in a library to edit a single page and can’t use the library’s search bar, this can become a huge pet peeve.
  • Limited to a single site collection: If you have multiple site collections composing your intranet/extranet/public website, you cannot share a single navigation term set among all of the site collections.  For me, this is a major sore spot as its not possible to share global navigation across site collections, let alone the more granular levels of navigation.  I don’t want to have to maintain multiple copies of a navigation term set manually so that whenever I click a ‘Home’ link across site collections, I go to the same page.

Code
Below are some code samples just to get started using managed navigation programmatically.
I found myself having difficulty trying to figure out how to access the friendly URL for a term, because I couldn’t find the properties or methods I needed on the Term object.  You must first get the NavigationTerm object for the Term, then you can get the friendly URL.

   1: TermSetCollection navTermSets = session.DefaultSiteCollectionTermStore.GetTermSets(NavTermSetName, 1033);

   2: 

   3: //gets the collection of terms starting at the root term 'value'

   4: var termCollection = from allTerms in navTermSets[0].Terms where allTerms.GetDefaultLabel(1033).ToLower() == "value" select allTerms;

   5: 

   6: if (termCollection != null && termCollection.Count() > 0)

   7: {

   8:     //gets the root term, 'value'

   9:     Term term = termCollection.First();

  10:     NavigationTerm navTerm = NavigationTerm.GetAsResolvedByWeb(term, web, "GlobalNavigationTaxonomyProvider");

  11:     string friendlyUrl = navTerm.FriendlyUrlSegment.Value;

  12: }

 
If you want to go the other direction, from the physical page to the friendly URL you would used the following code snippet.

   1: //get the pages library

   2: Guid pagesId = PublishingWeb.GetPagesListId(web);

   3: SPList publishingPages = web.Lists[pagesId];

   4: 

   5: //get a reference to whichever page you want

   6: SPListItem page = publishingPages.Item[0];

   7: 

   8: //a page can have multiple friendly URLs

   9: IList<NavigationTerm> friendlyUrls = new List<NavigationTerm>();

  10: friendlyUrls = TaxonomyNavigation.GetFriendlyUrlsForListItem(page, true);

  11:

To set the target URL programmatically, you have to set the Value property of the Navigation Term’s TargetUrl property.  In this example, I’m using a hard coded physical URL, you would most likely get this value dynamically.

   1: NavigationTerm navTerm = NavigationTerm.GetAsResolvedByWeb(term, web, "GlobalNavigationTaxonomyProvider");

   2: navTerm.TargetUrl.Value = "~sitecollection/Pages/testpage.aspx";

Just for good measure, below is a code snippet for getting the Navigation Term and friendly URL and setting the TargetUrl property using Powershell if you prefer to go that route.

   1: $taxonomySite = Get-SPSite -Identity $SiteUrl

   2: $taxonomySession = Get-SPTaxonomySession -site $taxonomySite

   3: $taxonomyTermStore =  $taxonomySession.TermStores | Select Name

   4: $termStore = $taxonomySession.TermStores[$taxonomyTermStore.Name]

   5:

   6: #make sure these 2 lines match your environment

   7: $group = $termStore.Groups["Group name"]

   8: $termSet = $group.TermSets["Term set name"]

   9:

  10: foreach ($term in $termSet.GetAllTerms())

  11: {

  12:     $navTerm = [Microsoft.SharePoint.Publishing.Navigation.NavigationTerm]::GetAsResolvedByWeb($term, $taxonomySite.RootWeb, "GlobalNavigationTaxonomyProvider")

  13: 

  14:     #get friendly URL

  15:     $friendlyUrl = $navTerm.FriendlyUrlSegment.Value

  16: 

  17:

  18:     #to set target URL

  19:     $navTerm.TargetUrl.Value = "~sitecollection/Pages/testpage.aspx"

  20: }

  21: 

  22: #to save all changes you made to term set

  23: $termStore.CommitAll()

 
Again, if you want to go the other direction using Powershell, see below.

   1: #Get the Publishing Web and pages within it

   2: $pagesId = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPagesListId($web)

   3: $publishingPages = $web.Lists[$pagesId]

   4: $page = $publishingPages.Items[0]

   5: 

   6: $friendlyUrls = [Microsoft.SharePoint.Publishing.Navigation.TaxonomyNavigation]::GetFriendlyUrlsForListItem($page, $true)

   7: 

   8: if ($friendlyUrls.Count -ne $zero)

   9: {

  10:     $friendlyUrls | ForEach-Object{

  11:     $friendlyUrl = $_.GetWebRelativeFriendlyUrl()

  12: 

  13:     #code here for what you want to do w/ the friendly URL

  14: }

  15: 

  16: #if you want to access a navigation property like below

  17: $field = $page.Fields["Hide physical URLs from search"]

  18: $physUrlHidden = $page.GetFormattedValue($field.Title)]

Thoughts on “SharePoint 2013 Managed Navigation: Pros, Cons, and Code”

  1. Con: It only works with publishing pages. When you have e.g. Team Site links in your navigation with MDS enabled, they sometimes work, sometimes they don’t. Any site with MDS doesn’t really work due to the nature of the links.

  2. I have also found that managed navigation only works reliably on publishing sites. I am migrating a client from SharePoint 2010 to SharePoint 2013 and we are splitting out site collections because of the size of the current database. They use a lot of Document Center and Team Site site templates, for thousands of sites mind you. I am unable to get the managed navigation to work on any sites below the root without making a ‘simulated’ change to the Navigation settings. I have a post on MSDN forums explaing the entire issue: http://social.msdn.microsoft.com/Forums/en-US/sharepointgeneral/thread/87a00e4f-59eb-4e36-a7f0-6535bb1f748a
    I opened a support ticket with Microsoft and so far after a month, next to no response. I have to save face with my client because of something OOTB that *should just work*, meanwhile Microsoft has absolutely no answer for me. How are we supposed to push client adoption with bugs in features that should work no matter the site template! So far I am not impressed!

  3. Pingback: Global Navigation in SharePoint 2013 | SharePoint O'Toole

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Mercedes Bernard

More from this Author

Follow Us