Friday, November 8, 2013

Managed Metadata Driven Breadcrumb Control - SharePoint 2013

One of the new capabilities in SharePoint 2013 is Managed Navigation, which allows us to define site's navigation using Managed Metadata (Taxonomy TermSet). Managed navigation facilitates SEO optimizations as well as user friendly URLs.

This is an example of creating taxonomy driven breadcrumb.

1. First create the term set in Managed Metadata Service in central admin.

2. Then from the site settings -> navigation, select the option Managed Navigation in the Global Navigation section.

3. Select the term set for the Global Navigation

4. In Visual Studio, create a web control like below. It uses TaxonomyNavigationContext class to get navigation information for the current HTTP request.

public class TestBreadCrumb : WebControl
{
 protected override void CreateChildControls()
 {
  try
  {
   SPSecurity.RunWithElevatedPrivileges(delegate
   {
    SPWeb web = SPContext.Current.Web;
    string siteurl = web.Site.ServerRelativeUrl;

    SortedList<int, NaviTerm> naviterms = new SortedList<int, NaviTerm>();
    int i = 1;
    TaxonomySession session = new TaxonomySession(SPContext.Current.Site);
    TaxonomyNavigationContext tnx = TaxonomyNavigationContext.Current;

    if (tnx.HasFriendlyUrl && tnx.FriendlyUrlTerm != null)
    {
     naviterms.Add(i, new NaviTerm { FriendlyUrl = "/" + tnx.FriendlyUrlTerm.FriendlyUrlSegment.Value, Title = tnx.FriendlyUrlTerm.Title.Value });
     this.GetParent(tnx.FriendlyUrlTerm, i, ref naviterms);
     // Add Home node
     naviterms.Add(naviterms.Count + 1, new NaviTerm { FriendlyUrl = string.Empty, Title = "Home" });
     this.RenderBreadCrumbs(naviterms, siteurl);
    }
   });
  }
  catch (Exception)
  { }
}

 // Recursively get parent nodes and add to the collection
 private void GetParent(NavigationTerm currentNode, int i, ref  SortedList<int, NaviTerm> terms)
 {
  NavigationTerm parentTerm = currentNode.Parent;
  if (parentTerm != null)
  {
   terms.Add(++i, new NaviTerm { FriendlyUrl = "/" + parentTerm.FriendlyUrlSegment.Value, Title = parentTerm.Title.Value });
   this.GetParent(parentTerm, i, ref terms);
  }
 }

 private void RenderBreadCrumbs(SortedList<int, NaviTerm> oaterms, string siteUrl)
 {
  string previous = siteUrl;
  for (int j = oaterms.Count; j > 0; j--)
  {
   if (j == 1) // Render last node without a hyperlink
   {
    Literal lit = new Literal();
    lit.Text = oaterms[j].Title;
    this.Controls.Add(lit);
   }
   else // Render other nodes as links
   {
    HyperLink link = new HyperLink();
    link.Text = oaterms[j].Title;
    link.NavigateUrl = previous + oaterms[j].FriendlyUrl;
    this.Controls.Add(link);
    if (oaterms[j].FriendlyUrl != siteUrl)
    {
     previous = previous + oaterms[j].FriendlyUrl;
    }

    System.Web.UI.WebControls.Label lblSeparator = new System.Web.UI.WebControls.Label();
    lblSeparator.Text = " / ";
    this.Controls.Add(lblSeparator);
   }
  }
 }
}

public class NaviTerm
{
  public string FriendlyUrl { get; set; }
  public string Title { get; set; }
}

Notes:
Root of the site does not necessarily have a term assigned to it. So check whether there a friendly URL before retrieving term information.
Home link is added separately to the terms collection.
In order to display the breadcrumb, page needs to be accessed using the friendly URL.


The breadcrumb control can be added to the masterpage with the following code snippet.

<!--SPM:<%@Register TagPrefix="TestMPControls" Namespace="SharePointTestProject1" Assembly="SharePointTestProject1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a382f033b49257a3"%>-->
<!--CS: Start Create Snippets From Custom ASP.NET Markup Snippet-->
<!--MS:<TestMPControls:TestBreadCrumb runat="server" Id="Test_Breadcrum">-->
<!--ME:</TestMPControls:TestBreadCrumb>-->
<!--CE: End Create Snippets From Custom ASP.NET Markup Snippet-->

We can use “gacutil -l SharePointTestProject1” command to get the assembly information. SharePointTestProject1 is the assembly name.

Once done breadcrumb will be rendered as:

19 comments:

Ronald Valkenburg said...

Thanks for your post, can't wait to get this up running myself.

Can you please point out what steps to take in Visual Studio to get your code working? Ie what kind of project to start and how to add the file in which to paste your code.

Thanks!
Ronald

Prasad Sampath Wickramasinghe said...

Hello Ronald,
You can use SharePoint 2013 - Empty Project template and add a new class. Make sure to inherit from WebControl.

Anonymous said...

Thanks for the post. Do you see any performance issue with each page having a new taxomony session?

Anonymous said...

Nice Post :)
I wanted a way to be able to navigate back up the tree without loosing the refiners that had been applied. After a bit of debugging I found Srch.ScriptApplicationManager.get_current().navigateTo(url,true);
Also, instead of building the url through the friendly url segments you can use NavigationTerm.GetResolvedDisplayUrl(null).

Thanks for the post, seems like a pretty core feature was left out with the Managed Navigation...

Trevor

Anonymous said...

Thank you so much for posting this!!

I use it in my custom bootstrap master page now.

Unknown said...

Prasad,
Im trying to understand the reason, why you have created the web control for this, rather I was able to make this working with default PlaceHolderTitleBreadcrumb.
Because there are providers registered in the web.config for Taxonomy navigation

El Ingeniero said...

Hi Prasad.

We had implement your solution in a site with anonimous acces, but with a anonimous user the solution get this error: HasFriendlyUrl= False and with an autenticated users work fine.

Any idea of this?

Staygreen Academy said...

Information was good,i like your post.
Looking forward for more on this topic
SharePoint Administration Training in

Hyderabad

Anonymous said...

What are the namespace that need to be included? I am getting error in this.GetParent(...) and this.RenderBreadCrumb(....)

Anonymous said...

Ignore the above comment...

Unknown said...

Thank you for postining good information about SEO.
SaiSantoshTechnologies Offers search engine optimization and marketing services, text link brokering, directory submission service, and list of free
internet based SEO tools.

seo training in hyderabad

seo training in hyderabad

Unknown said...

amazing information
good going author

knowledge on seo shall bring added advantage to any people who are doing their self business
get training on seo , today
seo training in bangalore

Unknown said...

Hy,

Everything nice and supposedly easy from your descriptio. BUT how do we achieve this functionality. OK, create class, and add snippet in Master page:
1. What to do with that class after created in VS ? Deploy as solution ? How ?
2. Where to put the snippet in the master page ?
3. other important steps missing ?
4. please give more instructions

I would be gratefull if you can describe how you achieved this step by step

penile implant said...

That is great to hear, thank you for reading!

Urology Surgery in India said...

Great post and thanks for sharing....

best doctor for stem cell treatment in india said...

Cool thanks for the advice I’ll check it out!

Stem Cell Therapy for Vitiligo Cost in India said...

Thank you, that was just an awesome post!!!

Stem Cell Treatment for Diabetes Type 1 in India said...

Thanks for great article sharing...

Stem Cell Treatment for Diabetes Type 2 in India said...

Greetings and thank you very much for share