SharePoint 2013 Customize Display Template for Content By Search Web Part (CSWP) Part-1
1 Aug 2013 1:09 PM
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.
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.
Once your drive is mapped navigate to Display Templates --> Content Web Parts
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>
Few important points to note here:
AddPostRenderCallback(ctx, function() {
//code to execute
});
_#-->
There is another way to achieve this by using:
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
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$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>
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>
<!--#_
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>
-
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