Wednesday, May 29, 2013

Customizing Search Navigation on a SharePoint 2013 Publishing Site

Managed metadata-driven navigation in SharePoint 2013 lets us use clean and implementation-independent URLs, which are often required in WCM applications. I was working on a web presence site for my customer, which used clean URLs. A simple search interface was used on it: a search box on a master page, and a search results page containing search results web part, and a search box web part. I wanted that search box web part to have a drop-down list of options so the Internet users could choose whether to search the entire site, or just the blogs.

First of all, in the past with SharePoint 2010 and 2007 we were using scopes to achieve this effect. It works differently in SharePoint 2013. Under Site Settings >> Search Settings you need to define the links to different destination pages:

Fig. 1 - Site Collection Search Settings

These links would point at two different search results pages and pass user's search keywords as a query string to these pages. In my case the first link "All Results" was pointing at a site search results page, the second one "Blog Results" - at a blogs listing page.

Second of all, we need to configure the search box web part. If you want to use the drop-down menu in the search box residing on the master page then you simply need to select the option titled "Turn on the drop-down menu inside the search box, and use the first Search Navigation node as the destination results page." on the Fig. 1 above. In my case I wanted no drop-down menu there, but needed one on the search results page. This is done on the search box web part as shown on the Fig. 2.

Fig. 2 - Search Box ToolPart showing how to configure the drop-down menu

That's pretty easy and gets you what you need. There is one problem however. Look at the Search Settings page illustrated on Fig.1 - the URL is pointing at an ASP page, which we certainly would like to change from /auth/en-ca/Pages/Search-Results.aspx to something like /auth/en-ca/results. Should be simple, especially as exactly this is done under the "Which search results page should queries be sent to?" section on the same page. Well, turns out that it does not work if you attempt doing it through the UI - it will complain about incorrect URL format unless you give it a page reference.

These links are referred to as "Search Navigation nodes" for a reason. If you open PowerShell and check out the navigation of your current web, you will see the new property of Microsoft.SharePoint.Navigation.SPNavigation type named SearchNav there:

Fig. 3 - SearchNav is a new property of the SPNavigation type in SharePoint 2013

OK great. The next obvious thing to do is change the URL of the "All Results" Search Navigation node from /auth/en-ca/Pages/Search-Results.aspx to /auth/en-ca/results using the PowerShell. Guess what -  it would silently not update the URL property.

The way I have got it to work was by creating the navigation node entirely from PowerShell. I also had to use the SPNavigationNode constructor overload accepting a Boolean isExternal flag and set it to $true in order to bypass the URL check, which SharePoint does and for some reason ignores the managed metadata-based navigation URLs. So the PowerShell workaround in my case looks as follows:

$node1 = new-object `
 -TypeName "Microsoft.SharePoint.Navigation.SPNavigationNode" `
 -ArgumentList "All Results", "/auth/en-ca/results", $true
$node2 = new-object `
 -TypeName "Microsoft.SharePoint.Navigation.SPNavigationNode" `
 -ArgumentList "Blog Results", "/auth/en-ca/blogs", $true

$web = Get-SPWeb http://devserver2012/auth/en-ca

This gets all my URLs to be "clean", including the ones pointed at from the Search Box drop-down menus. Interestingly, after creating the links through PowerShell you can modify their title, description, or even the URL properties through the UI without issues.

I was running SharePoint Server 2013 with March 2013 CU.