Custom Refinement Panel for SharePoint 2010 Search based on Departments / Business Unit

Custom Refinement Panel for SharePoint 2010 Search based on Departments / Business Unit

Rate This
  • Comments 2

 

Scenario

Most of the organizations structure there departments or Business Units into separate site collections. For example all sites related to Human Resource, Finance, Management, Operations etc are grouped into separate site collection under one/multiple farms. Hence, there can be a requirement within search that the search results can be refined based on the department/business unit (site collections) name they are coming from.

Introduction

There is a requirement to enable user to have Business Units (Departments) as a search refiner in the refinement panel for any search made through the search page. The search is done across the farm and there is no metadata stored along with the searched content (list item as a column or document as a document property) to indicate in the refinement panel. This metadata is incorporated using XSL that transform the refinement xml into the refinement panel.

Here we have modified Search Refinement Webpart to get the intended result. Any Search Service can be used in this context.

Two different xml is been modified to get the intended result, which are as follows:

Filter Category Definition

A new category is required to be added to the category xml to the Refinement Panel WebPart. This is our custom category to indicate business unit. Also, ensure to uncheck Use Default Configuration option to enable our custom category to be displayed in refinement panel.

Refinement Panel

Property Value

Filter Category Definition

Add the following category below the site category:

<Category 
      Title="Department"
      Description="Which department this document is from"
Type="Microsoft.Office.Server.Search
.WebControls.ManagedPropertyFilterGenerator"
MetadataThreshold="1" NumberOfFiltersToDisplay="4" MaxNumberOfFilters="20" ShowMoreLink="True" MappedProperty="sitename" MoreLinkText="show more" LessLinkText="show fewer" ShowCounts="Count" />

Please ensure that the Category title is the same which you are going to use within XSL file to modify the appearance.

Use Default Configuration

Uncheck the same to enable custom categories to be displayed on refinement panel.

 

RefinerStyle.xsl

As indicated by above code, webpart also uses the custom XSL Stylesheet in order to display the custom refinement in a specific format that includes the department name along with the number of instance found. This XSL file resides in the root web of the web application at following path:

<RootWeb>/Style Library/XSL Style Sheet/RefinerStyle.xsl

The above URL is added to XSL Link property of the web part.

XSL Constraint

In order to map the search content to either of the Business Unit, we use the OOB refined managed property sitename which refines based on URL of the search content rolled up to Site Collection.

It is advised to make a copy of OOB XSL file and then make changes to it.

Within XSL we add a condition within <xsl:choose> element of Categories template, in order to provide special handling of the “Department” category.

Categories Template

Code
<xsl:when test="$ManagedProperty = 'sitename' and $DisplayName = 'Department'">
   <xsl:call-template name="Filter2">
    <xsl:with-param name="Filters" select="Filters/Filter" />
    <xsl:with-param name="ShowCounts" select="$ShowCounts" />
   </xsl:call-template>
</xsl:when>

After, that it only left at Filter template to modify incoming URL value to our custom values. For better implementation a copy of Filter Template is created with name Filter2 which is specific for our custom refinement category

Code
<xsl:template name="FilterLink2"> 
    <xsl:param name="Url"/> 
    <xsl:param name="UrlTooltip"/> 
    <xsl:param name="Value"/> 
    <xsl:param name="FilterSelection"/> 
    <xsl:param name="ShowCounts"/> 
    <xsl:param name="Count"/> 
    <xsl:param name="Percentage"/> 
    <xsl:param name="Indentation"/> 
    <xsl:variable name="OriginalUrl" select="$Url"> 
    </xsl:variable> 
    <xsl:variable name="SecureUrl"> 
        <xsl:call-template name="GetSecureUrl"> 
             <xsl:with-param name="Url" select="$Url" /> 
        </xsl:call-template> 
    </xsl:variable> 
    <li class="ms-searchref-filter {$FilterSelection}"> 
        <xsl:if test="($Indentation = '1')"> 
            <span class="ms-searchref-indenticon">&#8627;&#160;</span> 
        </xsl:if> 
        <a class="ms-searchref-filterlink" href="{$SecureUrl}" 
title="{$RefineByHeading}: {$UrlTooltip}"> <xsl:choose> <xsl:when test="contains($Value, '<url like demo2010a:33393>')"> <xsl:value-of select="'Human Resource'"/> </xsl:when> <xsl:when test="contains($Value, '<url like demo2010a:19295>')"> <xsl:value-of select="'Finance'"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="Value"/> </xsl:otherwise> </xsl:choose> </a> <xsl:choose> <xsl:when test="($ShowCounts = 'Count') and ($Count != '')"> <span class="ms-searchref-count"> <xsl:if test="$IsRTL = 'True'">&#x200f;</xsl:if> (<xsl:value-of select="Count"/>) </span> </xsl:when> <xsl:when test="($ShowCounts = 'Percentage') and ($Percentage != '')"> <span class="ms-searchref-count"> <xsl:if test="$IsRTL = 'True'">&#x200f;</xsl:if> (<xsl:value-of select="format-number($Percentage, '0%')"/>) </span> </xsl:when> </xsl:choose> </li> </xsl:template> <xsl:template name="Filter2"> <xsl:param name="Filters" /> <xsl:param name="ShowCounts" /> <xsl:for-each select="$Filters"> <xsl:variable name="Selection" select="Selection" /> <xsl:choose> <xsl:when test="($Selection = 'Selected')"> <xsl:call-template name="FilterLink2"> <xsl:with-param name="Url" select="Url" /> <xsl:with-param name="UrlTooltip" select="Tooltip" /> <xsl:with-param name="Value" select="Value" /> <xsl:with-param name="FilterSelection"
select="'ms-searchref-selected ms-searchref-removable'"/> <xsl:with-param name="ShowCounts" select="$ShowCounts" /> <xsl:with-param name="Count" select="Count" /> <xsl:with-param name="Percentage" select="Percentage" /> <xsl:with-param name="Indentation" select="Indentation" /> </xsl:call-template> </xsl:when> <xsl:when test="($Selection = 'Implied')"> <xsl:call-template name="FilterLink2"> <xsl:with-param name="Url" select="Url" /> <xsl:with-param name="UrlTooltip" select="Tooltip" /> <xsl:with-param name="Value" select="Value" /> <xsl:with-param name="FilterSelection"
select="'ms-searchref-selected'" /> <xsl:with-param name="ShowCounts" select="$ShowCounts" /> <xsl:with-param name="Count" select="Count" /> <xsl:with-param name="Percentage" select="Percentage" /> <xsl:with-param name="Indentation" select="Indentation" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="FilterLink2"> <xsl:with-param name="Url" select="Url" /> <xsl:with-param name="UrlTooltip" select="Tooltip" /> <xsl:with-param name="Value" select="Value" /> <xsl:with-param name="FilterSelection"
select="'ms-searchref-unselected'" /> <xsl:with-param name="ShowCounts" select="$ShowCounts" /> <xsl:with-param name="Count" select="Count" /> <xsl:with-param name="Percentage" select="Percentage" /> <xsl:with-param name="Indentation" select="Indentation" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:template>

Post Consideration

Since the mapping or the metadata about the department of the searched content resides within the xsl file. Any modification is required to be done on every instance of such xsl files (across the farm). The better approach here can be making a web service call (using JavaScript) to the centralized location where a mapping table can be maintained.

Custom Search Refinement Download Code here

Leave a Comment
  • Please add 4 and 2 and type the answer here:
  • Post
  • Nice post but you should include some print shots so we reader know how the outcome will look like.

  • +1 on Amber's comment

Page 1 of 1 (2 items)