SharePoint 2013 SEO Headaches – Managed Metadata Navigation “Feature” or “Bug”

Overview

I have been working on a new project recently to migrate existing SharePoint 2010 websites into SharePoint 2013.  One of the obvious benefits  for this migration is the ability to use Managed Metadata Navigation to create friendly Urls.  While this post is within the context of a SharePoint Migration, the “issue” or “feature” is not dependent on a migration and is apparent on new Site Collections.

The Requirement

The Requirements are very simple:

  • Create managed navigation to pages in the Site
  • Assign SEO metadata to each page to be displayed by Search Engines.
  • Create a Home navigation link to return the user to the Homepage of the site (this is the catalyst for the issue)
  • Confirm that all keywords and description meta-tags are appearing to end users.

The Solution

At first glance the solution appears simple.  Create a new Term Set, create some terms, assign a page to one or many terms, and then the rest is catered for you automatically.  However when trying to create the “Home” node I stumbled upon an issue.  Typically when you create managed metadata navigation you assign a friendly Url to every term (e.g. /about ,  /news ,  /contact ).

However, when you create a Home node you do not want to have the Url to this node to become “/home” you instead want it to go to “/” (the site root) instead.

termset-c

Customised Term to point to “/” homepage

 

SharePoint will gladly permit you to assign a forward slash (i.e. no term name) against a term and when you navigate back to your site the Navigation term exists, it goes to your homepage and you believe everything is right with the solution.  Wrong!

The Bug(s)

Performing these steps however has raised a couple of issues when trying to modify the SEO of the page.

Firstly a page assigned to a term which does not have friendly Url with any text in it (i.e. “/”) does NOT allow you to modify the SEO properties of the page.

metadata-d

If configured correctly this option is enabled like this.

The menu option is simply disabled if not configured correctly.

termset-b

Re-assigned Friendly URL to term

I thought that there may be an underlying issue with permissions on the page. After providing a friendly url for the page, the option magically becomes active and I can then set the SEO Settings.  I therefore filled in the properties and then after saving, reverted my term to remove the friendly url part and assume all is great. Wrong again!

This highlighted the second issue (and in my opinion more worrying one), which is when viewing the page as an anonymous user I now discover that it is missing the SEO metadata tags on the page (No keywords or description appears in my source code). Perhaps it didn’t save my SEO?  I retrace my steps and set a friendly url, check the page SEO settings, and see that they are all there. The term definitely has my SEO settings associated with it.  I go back to my page (now with a friendly URL) and I notice that the Keywords and Description meta tags are appearing in the page source.

It appears that if you do not properly assign a friendly url to a term like the image above, SharePoint will NOT render the controls correctly even though the term has associated metadata.

The Work Around

The workaround for this issue is quite a simple one, but none the less frustrating as it does not allow you to use relative URL’s in the Term set.  On your navigation term in the Term Store Management Tool, you need to assign the “Home” term to be “Simple Link or Header” rather than “Term-Driven Page with Friendly URL”. 

termset-a

Switch Node type to “Simple Link or Header”

By setting the term node type to a specific URL enables you to assign a term to a page like before (and therefore get the benefits of SEO) without losing the metadata tags off the homepage source.  The drawback to this is obviously that you are unable to use tokens e.g. ~sitecollection in this link or header block but I think this is a small price to pay for the required functionality.

Summary

Managed Navigation Term Sets in SharePoint 2013 are a fantastic addition to the SharePoint 2013 Toolset and really makes SharePoint 2013 as a Website Platform that much more flexible and competitive with alternatives.  I hope this post helps some people out there.

 

SharePoint 2013 – Developer Quirks and Tips – Display Rating Stars in the Content By Search WebPart

dev-tips-header-ratings

Overview

In SharePoint 2010, a common requirement from end users was the ability to display rating stars in Content Query WebParts.  A very popular and useful solution which was blogged about could be found here: (http://geeksthenewblack.wordpress.com/2010/10/29/show-rating-stars-in-the-content-query-web-part/) .  This solution used XSLT to display the stars and render out a set of images depending on the number rated.  So how can we get the same effect in the SharePoint 2013 CSWP, which uses javascript display templates to render its data?

The Problem

While the solution from SharePoint 2010 is a great one, it cannot be as easily translated into 2013 because of the way SharePoint 2013 handles its ratings images.  In SharePoint 2010 it used the ratings.png file which looked like this: Ratings

Using this image and some simple css classes, you could easily display the rating how you required.  SharePoint 2013 OOTB rating control displays the ratings in different manner, with different images and different HTML making things more interesting for us developers.

The Solution

To resolve this issue, I created a very simple javascript function that accepts the number of ratings and the average rating count as parameters. It returns the HTML formatted in the correct format used by the out of the box control.  This javascript does not give you the ability to UPDATE the rating, but will enable you to display ratings in a consistent “SharePoint Styled” manner.

Function

Example Usage in Display Template 

When using the code above in a display template, you need to add the required managed properties for RatingCount and AverageRating into your template so the properties can be retrieved.  (Note: you may need to ensure that your managed properties are available in your Search Service)

 Output

If you have managed to add the items in correctly, then you will be presented with something that looks similar to this:

rating-stars-lisp

 

As you can see, they appear just like they would from the OOTB rating control and give your end users a nicer experience in their display templates.

Any problems let me know.

 

LifeInSharePoint – Metro Weather Updated to new API

Overview

This is just a quick note that the Metro Weather WebPart has been updated to take into consideration the latest API as the old one was now out of date.  Can you also please check your API keys as many may expire on the 31st August.

Download the new WSP here.

https://lifeinsharepoint.codeplex.com/releases/view/101035

Thanks and sorry for the delay.

Why I have been so quiet, and what I am going to do about it.

Summary

As many of my readers may have noticed, I have not posted for a couple of months and this is something that I would really like to change soon.  The reason for my lack of posts is due to working on my first Responsive SharePoint 2013 public facing website which I have been working on furiously for the last two months with a team of developers at my job at ICS Solutions Ltd.  The project was for Northampton University and they wanted to migrate their website from their current CMS system called Jadu and instead host their website on SharePoint 2013.  What made this website even more interesting was that the website was hosted in Microsoft Azure’s IAAS which not only enabled awesome scalability but a much easier and faster infrastructure build.

The SharePoint project took advantage of so many fantastic features that comes as part of SharePoint 2013 such as Managed Metadata Navigation (Friendly Urls), Content by Search WebPart (CSWP), SharePoint Catalogs, and the much improved search service in SharePoint 2013.  It is my plan to give an outline as to how the project was designed, how the project was developed and as many of the “gotchas” that I suffered along the way so that hopefully you do not stumble upon the same issues that we faced.  Before this happens however I am taking a much needed holiday to de-stress but keep your eyes pealed for a “How we did it” series soon.

For those interested in the website please visit http://www.northampton.ac.uk and provide some feedback in the comments below.

See you all soon.

Quick Tip – SharePoint 2013: Get Managed Navigation Term for Current Page in Code

quicktips

I have recently been building alot of new functionality in SharePoint 2013 and wanted to extend my Promoted Links WebPart to enable me to place the WebPart on a publishing website page layout and then have each page display a different set of links depending on which links in the list were tagged.  I was able to easily add a new managed metadata column which used the Managed Navigation Term set for the current site collection as its source so that I was able to select which page to display however I was unable how to change my WebPart to understand what the current pages term was.  Having used the Content by Search WebPart I was aware that this has the functionality built so obviously it should be a fairly simple process.

I also know there is an OOTB WebPart called the Term Property WebPart which enables you to display properties based on a specific term or properties based upon the current context.  Using this WebPart however would not be an option as there is no connection properties on this WebPart.

To find the solution I dug around the MSDN technical documentation for 2013 and came across the TaxonomyNavigationContext class (http://msdn.microsoft.com/en-gb/library/microsoft.sharepoint.publishing.navigation.taxonomynavigationcontext.aspx)  This class was the answer to my problem, and by passing your current context you can easily get the information you need. e.g.

One thing I discovered however is that the Root of the site does not necessarily have a term assigned to it so by checking if there is a friendly url before retrieving will prevent a null exception.