SharePoint 2013: Custom Display Template for Content Search Web Part

Content Search Web Part
The Content Search Web Part (CSWP) is a new web part since SharePoint 2013. The CSWP is a very powerful tool which uses search queries to display dynamic content from the SharePoint search index. Instead of using XSLT to style and format the results, CSWP uses display templates. A major advantage of the CSWP is the ability to query content from the whole farm, the biggest downside is the dependence on the search crawl. In this post I will go over the basic structure of the CSWP and how to create custom Display Templates.

CSWP vs CQWP
Both the CSWP and the CQWP have pro’s and con’s, depending on the situation one will be the best.

Pro’s
CSWP CQWP
 Farm wide results  Major and minor versions
 HTML and JavaScript  Near to instant results
 Build in paging  Build in grouping

 

Con’s
CSWP CQWP
 Crawl dependent  Site collection wide results
 Only major versions  XSLT 1.0
 No build in grouping  No build in paging

 

Display template
Display Templates are used for the CSWP and for the search results in search. With the Display Templates we can control which content (managed properties) are shown and how they are displayed, with the use of JavaScript we can even add advanced logic. Every CSWP uses two Display Templates, one Control Template and one Item Template. Remember always edit the HTML files not the JS files.

The Control Template will only be rendered once and will provide the overall structure for the results, the structure contains the heading and footer of the result set. The Item Template will be rendered once for each result and provide the structure for all the shown result.

DisplayTemplate

More information about the display templates can be found on MSDN Display Templates and MSDN Content Search Web Part.

Files and location
The display templates are located in a folder within the master page gallery.

/_catalogs/masterpage/Display Templates/Content Web Parts

The files follow a naming convention, files start with Control or Item. Based of the name of the file we can determine which type of display template it is.

  • Files starting with Control are Control templates
  • Files starting with Item are Item templates.

For every display template there are two file types a HTML and a JS. When editing the display templates we only edit the HTML files, never the JS files. SharePoint will automatically update the JS files based on the changed we make to the HTML.

Customize Control Templates

When customizing display template I always copy an existing template as a start point, editing SharePoint standard files is not a best practice. After copying the file use the UI to set the properties content type, title, description, hidden template and control type. Setting the properties through the UI lowers the change of setting the references incorrectly.

settingpropertoescontrol

The settings are located in the header tag of the HTML file, you can change the settings here too.

<head>
<title>Lijst met paginering</title>

<!--[if gte mso 9]><xml>
<mso:CustomDocumentProperties>
<mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden>
<mso:MasterPageDescription msdt:dt="string">This is the description</mso:MasterPageDescription>
<mso:ContentTypeId msdt:dt="string">0x0101002039C03B61C64EC4A04F5361F385106601</mso:ContentTypeId>
<mso:TargetControlType msdt:dt="string">;#Content Web Parts;#</mso:TargetControlType>
<mso:HtmlDesignAssociated msdt:dt="string">1</mso:HtmlDesignAssociated>
</mso:CustomDocumentProperties>
</xml><![endif]-->
</head>

With display templates we often need to include JavaScripts, scripts can be added within the script block. The script block is located just below the first body tag.

<script>
   $includeLanguageScript(this.url, "~sitecollection/_catalogs/masterpage/Display Templates/Language Files/{Locale}/CustomStrings.js");
</script>

After the script block the main div starts, by default the id tag matches the control template name. The template needs to have this main div, even though it will not be rendered on the page.

 <div id="Control_ListWithPaging_Custom">

Within this div we need to create all the logic, variables and HTML. JavaScript will be located within the special command tags and the HTML will be located outside of the tags. The tags are required for the SharePoint engine to be able and convert the HTML correctly to JavaScript.

<!--#_  _#-->

It is also possible to add the JavaScript within the HTML, simply add the following tags around the variable.

_#= =#_

The header of the Control Template is defined within the UL tag, this tag also contains the reference to the actual search results which are rendered by the Item Template.

_#= ctx.RenderGroups(ctx) =#_

After the UL tag we can add code to show in the footer. For example a hyperlink to a information page.

<div>
   <a href="/info.aspx">More info</a>
</div>

The Control Template also renders the HTML when there are no item. Within this if statement we can change what happens when there are no results. By default SharePoint shows the noResults variable.

<!--#_
if (ctx.ClientControl.get_shouldShowNoResultMessage())
{
_#-->
        <div class="_#= noResultsClassName =#_">_#= $noResults =#_</div>
<!--#_
}
_#-->

 

Customize Item Templates
Customizing Item Templates is similar to customizing Control Templates. This will result in some duplicate explanations. When customizing Item Template I always copy an existing template as a start point, editing SharePoint standard files is not a best practice. After copying the file use the UI to set the properties, content type, title, description, hidden template and control type. Do not set the ManagedPropertiesMapping through the UI, in my experience this does not always work correct. Setting the properties through the UI lowers the change of setting the references incorrectly.

settingpropertoescontrol

The settings are located in the header tag of the HTML file. The ManagedPropertyMapping is used to map all the Search Managed Properties to the Item Template. We will need to add all the required properties to the header.

<head>
<title>Two lines</title>

<!--[if gte mso 9]><xml>
<mso:CustomDocumentProperties>
<mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden>
<mso:ManagedPropertyMapping msdt:dt="string">'Link URL'{Link URL}:'Path','Line 1'{Line 1}:'Title','Line 2'{Line 2}:'','FileExtension','SecondaryFileExtension'</mso:ManagedPropertyMapping>
<mso:MasterPageDescription msdt:dt="string">This Item Display Template will show a small thumbnail icon next to a hyperlink of the item title, with an additional line that is available for a custom managed property.</mso:MasterPageDescription>
<mso:ContentTypeId msdt:dt="string">0x0101002039C03B61C64EC4A04F5361F385106603</mso:ContentTypeId>
<mso:TargetControlType msdt:dt="string">;#Content Web Parts;#</mso:TargetControlType>
<mso:HtmlDesignAssociated msdt:dt="string">1</mso:HtmlDesignAssociated>
</mso:CustomDocumentProperties>
</xml><![endif]-->
</head>

The syntax for adding properties is as follows. Personally I find it very helpful to keep the property name equal to the managed property name. For more information about adding properties go to SteveMann’s Path blog post about this subject.

'[property name for us in template]':'[managed property from search]'

After adding all the managed properties we need to make JavaScript variables to make the actual result values available within the Item Template. The variables are added within the JavaScript tags inside the main div. This is also the location where we can create the JavaScript logic, in later blogs I will go further into this. In this example I added the property ArticleStartDate.

var ArticleStartDate = ctx.CurrentItem.ArticleStartDateOWSDATE;

With display templates we often need to include JavaScripts, scripts can be added within the script block. The script block is located just below the first body tag.

<script>
   $includeLanguageScript(this.url, "~sitecollection/_catalogs/masterpage/Display Templates/Language Files/{Locale}/CustomStrings.js");
</script>

Finally we need to show the search results values in a proper layout with styling. Within the main div we can add and change the HTML to display the results in anyway.

<div class="Container" id="_#= dataContainerId =#_">
   <a class="ms-displayBlock" href=" _#= linkURL =#_ " title="_#= $htmlEncode(Titel.defaultValueRenderer(Titel)) =#_" id="_#= TitelLinkId =#_">_#= Title =#_</a>
<div class="Date">_#= localArticleDate.format("dd-MM-yyyy") =#_ - _#= Location =#_ </div>
<div class="ItemSubLineLight">_#= PublishingPageContent=#_</div>


Tips

  •  Us the UI to set properties
  • Never edit the JavaScript generated by SharePoint
  • Enable continues crawl
  • When reusing code or templates check all the references
  • Follow the file naming convention

Links

SharePoint 2013 CQWP Office Online hyperlink

With the introduction of Office Online (Office web apps) files can be opened in the browser with Office Online (Office web apps) or with the local client. If able SharePoint 2013 will open files (.pptx, docx, xslx) in office Online and other files in the related client (doc, xsl, pdf etc.) This behavior works great within the document library, however this does not work out of the box for files that are displayed using a content query webpart. With XSLT we are able to create an variable which creates per file the required hyperlink.

Solution
1. Edit the CQWP Template where the semi dynamic hyperlink is required.
2. First we need to create the variable that builds the correct office online or default hyperlink. The default hyperlink opens the files in the client software.

<xsl:variable name="DynamicURL">
   <xsl:choose>						
      <xsl:when test="contains(@FileExtension,'docx')">
         /sites/PH/OH/_layouts/WopiFrame.aspx?sourcedoc=<xsl:value-of select="@LinkUrl"/>	
      </xsl:when>
      <xsl:when test="contains(@FileExtension,'pptx ')">
         /sites/PH/OH/_layouts/WopiFrame.aspx?sourcedoc=<xsl:value-of select="@LinkUrl"/>	
      </xsl:when>
      <xsl:when test="contains(@FileExtension,'xslx')">
         /sites/PH/OH/_layouts/WopiFrame.aspx?sourcedoc=<xsl:value-of select="@LinkUrl"/>	
      </xsl:when>
      <xsl:otherwise>
         <xsl:value-of select="@LinkUrl"/>
      </xsl:otherwise>
   </xsl:choose>
</xsl:variable>

3. The choose function determines the file type and sets the correct Office Online hyperlink or the default Hyperlink based of LinkUrl field.
4. Secondly we need to use the DynamicURL variable to create the hyperlink.

<a href="{$DynamicURL}" target="_blank">
   <xsl:value-of select="@Name"/>
</a>

 

Result
Files with extensions docx, pptx and xslx will open in Office Online other files will open in the related client.

CQWP Hyperlink Office Online

SharePoint Custom Grouping with XSLT

For SharePoint solution where the look and feel or clean code is very important we often create custom header.xslt ContentQueryMain.xslt and ItemStyle.xstl files. The files are almost completely empty to provide us with maximal control. This also means we need to recreate functionality that normally works by default. A good example is the ability to group the results.

Solution
1. Create the custom XSLT files and link the files to the Content Query Web Part.
2. The following code is a complete example of a custom Content Query Main XSLT file. This code generates grouping.

<xsl:stylesheet
    version="1.0"
    exclude-result-prefixes="x xsl cmswrt cbq" 
    xmlns:x="http://www.w3.org/2001/XMLSchema"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:cmswrt="http://schemas.microsoft.com/WebPart/v3/Publishing/runtime"
    xmlns:cbq="urn:schemas-microsoft-com:ContentByQueryWebPart">
    <xsl:output method="xml" indent="no" media-type="text/html" omit-xml-declaration="yes"/>

  <xsl:key name="Grouping" match="Row" use="@GroupingColumn" />

  <xsl:template match="/">
 <xsl:for-each select="/dsQueryResponse/Rows/Row[generate-id(.)=generate-id(key('Grouping',@GroupingColumn))]/@GroupingColumn">
  <xsl:sort />
        <xsl:value-of select="."/>
        <xsl:for-each select="key('Grouping', .)">
         <br /><xsl:value-of select="@Title" />
         </xsl:for-each>
        <br/>
      </xsl:for-each>     
    </xsl:template>
</xsl:stylesheet>

3. Change the XSLT where needed

Result
CQWP Custom Grouping

Show Pictures with Slimbox in SharePoint

Pictures are an important part of a SharePoint site, it enriched the otherwise plain look and feel. With a little extra effort we can integrate Slimbox to show the pictures in a very slick and modern way.

Solution

1. Download Slimbox2 and jQuery, in this example I used jQuery 1.8.3 uncompressed.
2. Save the files in the Style Library of SharePoint. Note that not all the Slimbox files are required to be stored in SharePoint.
3. Include the jQuery javascript, the Slimbox javascript and the Slimbox CSS to the page, page-layout or the master page.

<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/slimbox2.js"></script>
<link rel="stylesheet" href="css/slimbox2-rtl.css" type="text/css" media="screen" />

5. Create a picture library and save a couple of pictures to the library. The picture library will provide the necessary thumbnails without any extra effort.
6. Add a CQWP to a page and query the pictures.
7. Create a XSLT that shows the small thumbnails of the pictures, for example in a banner view.

Slimbox Result 1

8. I created two variables for the default SharePoint Thumbnails, Thumbnail_w and Thumnbail_t. And used the following code to show the small thumbnail with a Slimbox link to the bigger thumbnail.

<a href="{$Thumbnail_w}" rel="lightbox" title="{@Title}">
   <img src="{$Thumbnail_t}" alt="alt" class="PhotoAppThumbnail" />
</a>

9. Also note that the title field is added to the Slimbox link, the title will be displayed on the Slimbox overlay.

Result

Slimbox Result 1

SharePoint 2013 Editable column in the Dataview and Quickedit

With the dataview and Quickedit view user are able to quickly edit multiple items and columns. The following overview contains a list of which columns are editable. Remember depending on the SharePoint 2013 version and updates different columns might be editable.

Overview

Column Type SP 2013 Cloud SP 2013 Onpremise
Title Editable Editable
Single Text Editable Editable
Multiple lines of Rich Text Editable Editable
Multiple lines of plain Text Editable Editable
Choice Editable Editable
Numbers Editable Editable
Currency Editable Editable
Date and Time Editable Editable
LookUp Editable Editable
Checkbox Editable Editable
Person and Group Editable Editable
Hyperlink Editable Editable
Hyperlink as Picture Editable Editable
Managed Metadata Editable Editable
Task Outcome Not Editable Not Editable
Calculated Not Editable Not Editable
Content type Not Editable Not Editable