SharePoint 2013 Customize Display Template for Content By Search Web Part (CSWP) Part-1

SharePoint 2013 Customize Display Template for Content By Search Web Part (CSWP) Part-1

  • Comments 18
  • Likes

This blog post will explore basics of customizing SharePoint 2013 Content By Search Web Part (CSWP) using Display Templates. In my next Post "SharePoint 2013 Customize Display Template for Content By Search Web Part (CSWP) Part-2" I will show how to use a JQuery Plugin with Display Templates and customize the look and feel of CSWP. 

Content By Search Web Part

Content By Search Web Part(CSWP) was introduced in SharePoint 2013. CSWP has power to display dynamic content from SharePoint search index, based on dynamic search queries. It uses Display Templates for styling and formatting search results on the page. A big advantage of using CSWP over CQWP is, there are no scope boundaries for getting data across sites. However freshness of results depends on the latest crawl on content.

Display Templates 

Display Templates are used with CSWP to format/style search result generated by CSWP search query. Display Templates control which managed property is shown in the search results and how they appear in the Web Part. Each Display Template has two files: an HTML version of the Display Template that you can edit in your HTML editor, and a .js file that is for SharePoint use and should never be modified. CSWP uses combination of two Display Templates, Control Templates and Item Templates to render results.                         

Control Template provides HTML to structure the overall layout for how you want to present the search results. For example, the Control Template might provide the HTML for a heading, beginning and end of a list. The Control Template is rendered only once in the Web Part.

Item Template provides HTML that determines how each item in the result set is displayed. For example, the Item Display Template might provide the HTML for a list item that contains a picture, three lines of text that are mapped to different managed properties associated with the item. The Item Display Template is rendered one time for each item in the result set. So, if the result set contains ten items, the Item Display Template creates its section of HTML ten times. 

 

 

 For more information about Display Templates, see the "Search-driven Web Parts and Display Templates" section in Overview of the SharePoint 2013 page model.

Explore Display Templates

In a SharePoint 2013 Publishing site, map a network drive to master pages gallery. Follow Map a network drive to the SharePoint 2013 Master Page Gallery.

Once your drive is mapped navigate to Display Templates --> Content Web Parts

 

 

 

Under Content Web Parts Library there are several file names starting with "Control_" and "Item_", files starting with Control are Control Templates and files starting with Item are Item templates. Also there are two file extensions for each file type .html and .js.

.js is strictly for SharePoint internal use and not to be changed by users. Throughout the post we will be using .html extension and SharePoint will automatically update .js based on changes we have made to .html.

 

Now let's open a Control Template and examine some important properties.

Explore Control Display Template

Following code is from one of my Custom Control Template that we will discuss in my next post.

Header Properties

This section has Display Template header properties that provide information to SharePoint about Display Template, <title> will be displayed under CSWP Edit Properties to choose from.

<title>JSlider</title>

<!--[if gte mso 9]><xml> <mso:CustomDocumentProperties> <mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden> <mso:MasterPageDescription msdt:dt="string">This is the default Control Display Template that will list the items. It does not allow the user to page through items.</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:HtmlDesignConversionSucceeded msdt:dt="string">True</mso:HtmlDesignConversionSucceeded> <mso:HtmlDesignStatusAndPreview msdt:dt="string">http://demo.contoso.com/sites/Jquery-displaytemplate-demo/_catalogs/masterpage/Display Templates/Content Web Parts/Control_JSlider.html, Conversion successful.</mso:HtmlDesignStatusAndPreview> </mso:CustomDocumentProperties> </xml><![endif]-->

Script Block

This section is used to reference JavaScript and CSS files.

 

<script>
        $includeLanguageScript(this.url,"~sitecollection/_catalogs/masterpage/Display Templates/Language Files/{Locale}/CustomStrings.js");
        $
includeScript(this.url,"~sitecollection/style library/slider/js/jquery-1.9.1.min.js");
        $
includeScript(this.url,"~sitecollection/style library/slider/js/jquery.slides.min.js");
        $
includeCSS(this.url,"~sitecollection/style library/Slider/css/example.css");
       
<!--$includeCSS(this.url, "~sitecollection/style library/Slider/css/font-awesome.min.css");-->
        $
includeCSS(this.url,"~sitecollection/style library/Slider/css/charm.css");
 
</script>

 DIV Block

Following the <script> tag is a <div> tag with an ID. By default the ID for this <div> tag matches the name of the Display Template file. The HTML or JavaScript you want the display template to render must be included inside this <div> tag. However, the tag itself is not included in the markup that is rendered on the webpage.

 

<div id="Control_List">
<!--#_ 
if (!$isNull(ctx.ClientControl) &&
!$isNull(ctx.ClientControl.shouldRenderControl) &&
!ctx.ClientControl.shouldRenderControl())
{
return "";
}
ctx.ListDataJSONGroupsKey = "ResultTables";
var siteURL = SP.PageContextInfo.get_siteServerRelativeUrl();
_#-->

<div class="container">
<div class="slides">

_#= ctx.RenderGroups(ctx) =#_
<a href="#" class="slidesjs-previous slidesjs-navigation"><i class="icon-chevron-left icon-large"></i></a>
<a href="#" class="slidesjs-next slidesjs-navigation"><i class="icon-chevron-right icon-large"></i></a>
</div>
</div>

<!--#_
AddPostRenderCallback(ctx, function(){

$.getScript(siteURL + "/style library/Slider/js/jquery.slides.min.js", function(){
$('.slides').slidesjs({
width: 940,
height: 528,
navigation: true
});
})
});
_#-->

</div>
 

Few important points to note here:

  •  Any JavaScript Code should be inside  <!--#_ <JavaScript Code> _#-->

  • Use value assigned to variable using _#=   example: <a  href ="_#=LinkURL=#_">

  • In Control Template  _#=ctx.RenderGroups(ctx) =#_  is used to render  HTML items (actual search results) from Item template.

  • For CSS styling, wrap _#=ctx.RenderGroups(ctx) =#_ with a div and apply css style, this will style all items coming from Item Template. Point to note here is, most outer <div>with ID matching template title will never render in HTML, so be careful not to apply style to outer <div>or it will never reflect.

  • To call a JavaScript function after Display Template is completely rendered use the AddPostRenderCallback function. I will use this function to call a JQuery Plugin in my next post.

               <!--#

           AddPostRenderCallback(ctx, function() {             

           //code to execute

            });

             _#-->

There is another way to achieve this by using:

ctx.OnPostRender = function() {

};

Explore Item Display Template

Now let's open Item Display Template from Display Templates --> Content  Web Parts folder.

Header Properties

In Item Template Header Property  <mso:ManagedPropertyMapping> is used to map Search Managed Properties, retrieved from search query and map them to fields on Item Display template.

<mso:ManagedPropertyMapping msdt:dt="string">'Picture URL'{Picture URL}:'PublishingImage;PictureURL;PictureThumbnailURL','Link URL'{Link URL}:'Path','Line 1'{Line 1}:'Title','Line 2'{Line 2}:'Description','Line 3'{Line 3}:'','SecondaryFileExtension','ContentTypeId', 'FileExtension'{FileExtension}:'FileExtension'</mso:ManagedPropertyMapping>

In order to use a Search Managed Property, it should be first added under ManagedPropertyMapping header. To get a list of all Managed Properties that are returned from Search query, I took a fiddler trace while testing query on CSWP. Properties under ResultRows element are returned by search query in JSON format and can be used in Display Template.

mso:ManagedPropertyMapping: This property takes the managed properties that are used by search and maps them to values that can be used by the Display Template. The property is a comma-delimited list of values that uses the following format: 'property display name'{property name}:'managed property. For example: 'Picture URL'{PictureURL}:'PublishingImage;PictureURL;PictureThumbnailURL'.

For more Information about Mapping Input Properties checkout http://msdn.microsoft.com/en-us/library/jj945138.aspx#bk_mapproperties

Same as Control Template, Item Template also has Script Block and Outer DIV with matching DIV ID as template name.

DIV Block

Scripting should be put under outer DIV. After you map a property in header, you can get its value in script by using the following code:

var pictureURL =$getItemValue(ctx, "Picture URL");

The second parameter that is passed to $getItemValue() must match the property display name in single quotes used in the ManagedPropertyMapping element. In this example, Picture URL is the property name that is passed to $getItemValue(). Following code shows DIV section from my custom Item template.

<div id="Item_PictureJSlider">

<!--#_

var encodedId = $htmlEncode(ctx.ClientControl.get_nextUniqueId() + "_picture3Lines_");
var linkURL = $getItemValue(ctx, "Link URL");
linkURL.overrideValueRenderer($urlHtmlEncode);
var line1 = $getItemValue(ctx, "Line 1");
var pictureURL = $getItemValue(ctx, "Picture URL");
var containerId = encodedId + "container";

var dataDisplayTemplateTitle = "ItemPicture3Lines";

_#-->

       
<divclass="cbs-sliderContrainer"id="_#= containerId =#_"data-displaytemplate="_#= $htmlEncode(dataDisplayTemplateTitle) =#_">
          
<ahref="_#= linkURL =#_"title="_#= $htmlEncode(line1) =#_"target="_blank">
               
<imgsrc="_#= pictureURL =#_"width="570"height="270">
           
</a>

          
</div>
        
</div>

In above example ,all items returned by search will be rendered using HTML in inner DIV with class "cbs-sliderContrainer". Following screenshot is of rendered Display Template using IE developer tool (F12) . Notice DIVs with class "cbs-sliderContrainer", these are items coming from Item Template and they are wrapped in outer DIV class "slides" which is coming from Control template.

This post builds basics of Display Templates, my next post will focus on using JQuery Plugin to customize Display Templates!

 

http://blogs.technet.com/b/sharepoint_quick_reads/archive/2013/08/02/sharepoint-2013-customize-display-template-for-content-by-search-web-part-cswp-part-2.aspx

 

Comments
  • Good Work!!!

  • Thanks Suresh! Glad you liked it!

  • Hi Siraj,

    thanks for explaining Display templates !!

    Please clarify about following lines

    <div id="Item_PictureJSlider">

    <!--#_

    var encodedId = $htmlEncode(ctx.ClientControl.get_nextUniqueId() + "_picture3Lines_");

    here what is _picture3Lines_?

    how to get this value?

    regards,

    Swati

  • Hi Swati,

    "_picture3Lines_" is just a static string to generate encodedId, which i have used to generate Div Id. you can use any string here, this will be helpful when using jquery to find an element within DOM.

    checkout part 2 for more details on using JQuery blogs.technet.com/.../sharepoint-2013-customize-display-template-for-content-by-search-web-part-cswp-part-2.aspx

  • Good post..  Thank you..

  • Glad you like it! Thanks!

  • Very awesome, Siraj!

  • Thank you Tahir! I am glad you liked it!

  • Extremely good post, very helpful indeed :)

    A question: I need to display a user thumb in a list that displays recent blog posts, however I cannot figure out how to get the actual user thumb that resides on MySite, all I've accomplished so far is to display the "dummy" author thumb. Hope you can point me in the right direction.

    regards Thomas

  • how can I call a javascript function from an anchor tag click

  • hi karan, this is a custom anchor tag inside display template.

    sortByDate() is a js function

  • Nice Blog Very Help ful

  • This has been asked many times but I never found any explanation. If I want to render groups similar to how the CQWP allowed grouping where exactly would I do that. I assume it would have to be created in the Item template but I have not seen any examples. I am aware that there is a Group template but I don't know how to specify one. Without grouping the display the CSWP is not very useful since you may want to rollup content from many locations and group the results in a single CSWP. I have worked around this by refining the results into multiple CSWPs and than tabifying those but thats not dynamic at all. Any ideas or resources you could point me at. Thanks in advance.

  • Hi

    In the case of a cloned OOTB Slideshow display template I wondered if it was possible to dynamically change it the web part tool panel settings via a post back function so the slide show can adjust what is displayed in response to the number of items returned...

  • Hi,

    How to call javascript function in the anchor tag in the search display template.

    Thanks

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment