Building Custom Display Templates for OpenSearch Content

One of the less-used features of SharePoint Search (2013 or SPO) is the ability to federate to non-SharePoint sources that support the OpenSearch 1.1 protocol. Moreover, there isn’t a lot of documentation out there about what to do with those results once you have them or how to format them to fit in with the design of your SharePoint site.

In this post, I will show you how to build a custom display template using a federated result coming from an OpenSearch source.

OpenSearch Result Structure

As I started to dive into this, the first question I had was what managed properties are returned when going to an OpenSearch source? Using the search query tool, I was able to see that the default MP’s returned with a federated result are:

  • HitHighlightedSummary
  • LastModifiedTime
  • OpenSearchSingleResultXML
  • Path
  • piSearchResultId
  • RenderTemplateId
  • ResultTypeId
  • Title

The two most interesting properties in my opinion were the HitHighlightedSummary and the OpenSearchSingleResultXML. The former, also known as the dynamic teaser, should provide a snippet of the content that is relevant to the query. In my observation, however, it’s really just a snippet of the first sentence of the article so not a true dynamic teaser. The latter MP provides some raw XML about the document. Worth noting is that the HitHighlightedSummary seems to match the description sub-element of that XML.

This XML provides two other elements that I think might provide some value to our result display.

  1. PubDate: While this is repeated in my LastModifiedTime managed property, it’s already nicely formatted for me in the raw result.
  2. News:Source – This provides me with the source of the content. Certainly this will be interesting to our user.

Now that we know what our data looks like, let’s get to work building a custom display template.

Initialize Your Template

Go to the Design Manager and select Edit Display Templates. This will provide you with a list of display templates that are already deployed on your system. Download one of the existing templates and start by editing that. I would suggest choosing a simple template (Item_TwoLines is a good one) and working off of that.

Now that you have a template, the first thing you need to do is include the relevant managed properties in the template to ensure they’re available in the template.

 <mso:ManagedPropertyMapping msdt:dt="string">
 'Link URL'{Link URL}:'Path','Line 1'{Line 1}:'Title','Line 2'{Line 2}:'',
 'FileExtension','SecondaryFileExtension','OpenSearchSingleResultXML'
 </mso:ManagedPropertyMapping>

Feel free to modify the other MP’s in this mapping as well but for the sake of this post, we’re primarily concerned with including the OpenSearchSingleResultXML managed property.

Now that we have that, we want to crack it open and get the information we need out of it using JavaScript from directly within our template. Here’s some sample code (relies on jQuery):

 var osxml = $getItemValue(ctx, "OpenSearchSingleResultXML");  xmldoc = $.parseXML(osxml.value);
$xml = $(xmldoc);
$newssource = $xml.find("News\\:Source");
$newsdate = $xml.find("pubDate");
 
var thenewssource = $newssource.text();
var thenewsdate = $newsdate.text();

In the first three lines of code, I use jQuery to create a DOM object out of the XML returned in the search result’s OpenSearchSingleResultXML field. Then, I can use standard jQuery lookup mechanisms to find the element of the DOM I need. You’ll notice that to get the news source, I had to escape the colon character with double back slash.

The final step is to render these data elements in the template display:

 <div class="cbs-Detail" id="_#= dataContainerId =#_">
    <div class="">_#= thenewssource =#_</div>
    <a class="cbs-Line1Link ms-displayBlock" href="_#= linkURL =#_" 
 title="_#= $htmlEncode(line1.defaultValueRenderer(line1)) =#_" 
 id="_#= line1LinkId =#_">_#= line1 =#_</a>
    <!—#_     if(!line2.isEmpty)     {         _#—>
        <div class="cbs-Line2" 
 title="_#= $htmlEncode(line2.defaultValueRenderer(line2)) =#_" 
 id="_#= line2Id =#_">_#= line2 =#_</div>
        <!--#_     }     _#—>
    <div class="">_#= thenewsdate =#_</div>
</div>

And that wraps it up. Now all you need to do it copy this template back into the Display Template library where we got it. You should rename the file so that it doesn’t overwrite the original template you copied and I suggest modifying the Title tag of the template so you can distinguish your new template from the original as well. I suggest something meaningful that describes the template, like “Open Search Bing News Item”.

I haven’t included additional details on the plumbing required to deploy display templates themselves. This blog post on Steve Peschka’s Share-n-dipity blog provides a pretty robust explanation of that process.