Home > SP 2013 > Display Templates in Search

Display Templates in Search

December 26, 2012 2:01 pm Leave a comment Go to comments

In SharePoint 2010 if you wanted to render a particular item differently, it was a fairly arduous process of going in and modifying one HUGE chunk of XSLT in the core results web part. You got to practice your awesome XSLT skills and try and find the right place in that enormous document where to insert your custom code. Overall, it was a less than joyful experience.

With a display template, you have a few different things to keep track of:

1. Managed properties – you need to tell it what managed properties you need retrieved at query time. Those properties you can then use in your HTML, using a method I’ll describe below.

2. External JS and CSS – if you have any JavaScript or CSS files you want used with your display template then you can externalize them and add them to your display template.

3. Inline JS – you can also use inline JS in your display template. You just need to make sure that it is below the first <div> in your display template – also more on that below.

4. HTML – this is where you create the actual HTML for your display template that will render the results.

If you go into your search center site collection, Site Settings, then click on Master pages and page layouts link.

image

When you get into the library, click on the Display Templates folder, then click on the Search folder.

imageimageimage

In there you will find all of the display templates that are shipped out of the box. You will likely see a number of files that have the same name, but either a .html or .js suffix. All you care about are the .html files – the .js files are generated automatically when you upload an .html file.

Lets open up the default item template and look at the details of the same:

1. head tag

<head>
<title>Default Item</title>

<!–[if gte mso 9]><xml>
<mso:CustomDocumentProperties>
<mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden>
<mso:MasterPageDescription msdt:dt="string">Displays the default result item template.</mso:MasterPageDescription>
<mso:ContentTypeId msdt:dt="string">0x0101002039C03B61C64EC4A04F5361F385106603</mso:ContentTypeId>
<mso:TargetControlType msdt:dt="string">;#SearchResults;#</mso:TargetControlType>
<mso:HtmlDesignAssociated msdt:dt="string">1</mso:HtmlDesignAssociated>
<mso:ManagedPropertyMapping msdt:dt="string">’Title’:’Title’,’Path’:’Path’,’Description’:’Description’,’EditorOWSUSER’:’EditorOWSUSER’,’LastModifiedTime’:’LastModifiedTime’,’CollapsingStatus’:’CollapsingStatus’,’DocId’:’DocId’,’HitHighlightedSummary’:’HitHighlightedSummary’,’HitHighlightedProperties’:’HitHighlightedProperties’,’FileExtension’:’FileExtension’,’ViewsLifeTime’:’ViewsLifeTime’,’ParentLink’:’ParentLink’,’FileType’:’FileType’,’IsContainer’:’IsContainer’,’SecondaryFileExtension’:’SecondaryFileExtension’,’DisplayAuthor’:’DisplayAuthor'</mso:ManagedPropertyMapping>
</mso:CustomDocumentProperties>
</xml><![endif]–>

</head>

There is a tag called mso:ManagedPropertyMapping where you put in the managed properties your display template requires.

2. body tag

<body>
    <div id="Item_Default">
<!–#_
        if(!$isNull(ctx.CurrentItem) && !$isNull(ctx.ClientControl)){
            var id = ctx.ClientControl.get_nextUniqueId();
            var itemId = id + Srch.U.Ids.item;
            var hoverId = id + Srch.U.Ids.hover;
            var hoverUrl = "~sitecollection/_catalogs/masterpage/Display Templates/Search/Item_Default_HoverPanel.js";
            $setResultItem(itemId, ctx.CurrentItem);
            if(ctx.CurrentItem.IsContainer){
                ctx.CurrentItem.csr_Icon = Srch.U.getFolderIconUrl();
            }
            ctx.currentItem_ShowHoverPanelCallback = Srch.U.getShowHoverPanelCallback(itemId, hoverId, hoverUrl);
            ctx.currentItem_HideHoverPanelCallback = Srch.U.getHideHoverPanelCallback();
_#–>
            <div id="_#= $htmlEncode(itemId) =#_" name="Item" data-displaytemplate="DefaultItem" class="ms-srch-item" onmouseover="_#= ctx.currentItem_ShowHoverPanelCallback =#_" onmouseout="_#= ctx.currentItem_HideHoverPanelCallback =#_">
                _#=ctx.RenderBody(ctx)=#_
                <div id="_#= $htmlEncode(hoverId) =#_" class="ms-srch-hover-outerContainer"></div>
            </div>

<!–#_
        }
_#–>
    </div>
</body>

JavaScript is added immediately after the first DIV tag in your display template.

<!–#_
if(!$isNull(ctx.CurrentItem) && !$isNull(ctx.ClientControl)){
var id = ctx.ClientControl.get_nextUniqueId();
var itemId = id + Srch.U.Ids.item;
var hoverId = id + Srch.U.Ids.hover;
var hoverUrl = "~sitecollection/_catalogs/masterpage/Display Templates/Search/Item_Default_HoverPanel.js";
$setResultItem(itemId, ctx.CurrentItem);
if(ctx.CurrentItem.IsContainer){
ctx.CurrentItem.csr_Icon = Srch.U.getFolderIconUrl();
}
ctx.currentItem_ShowHoverPanelCallback = Srch.U.getShowHoverPanelCallback(itemId, hoverId, hoverUrl);
ctx.currentItem_HideHoverPanelCallback = Srch.U.getHideHoverPanelCallback();
_#—>

Also, it needs to go between an opening and closing tag set that looks like this: <!—#_ and _#—>, if you do not have your JavaScript between these tags it will not execute

Html is added between tags:

<div id="_#= $htmlEncode(itemId) =#_" name="Item" data-displaytemplate="DefaultItem" class="ms-srch-item" onmouseover="_#= ctx.currentItem_ShowHoverPanelCallback =#_" onmouseout="_#= ctx.currentItem_HideHoverPanelCallback =#_">

_#=ctx.RenderBody(ctx)=#_
<div id="_#= $htmlEncode(hoverId) =#_" class="ms-srch-hover-outerContainer"></div>

</div>

Lets take a closer look at JavaScript and Html script blocks above:

JavaScript block initializes a set of variables and used by Html block to output, for rendering any variable declared in JavaScript use syntax  _#= variable or managed property=#_ as seen in

<div id="_#= $htmlEncode(hoverId) =#_" class="ms-srch-hover-outerContainer"></div>

Managed properties are all available in an object called ctx.CurrentItem, so in the above default template if I want to add Title Managed Property to Html block we can use

<a href="_#= ctx.CurrentItem.Path =#_" class="MyClass">_#= ctx.CurrentItem.Title =#_</a>

Remember the tag syntax _#= ctx.CurrentItem.Path =#_

 

How do you include custom CSS in to display template?

You can use SharePoint javascript function called $includeCSS to get my CSS file pulled down for the display template

<body>

<script>

$includeCSS(this.url, "./styles/mycustom.css");

</script>

 

Debugging display templates:

1. You can use F12 IE Toolbar or any other script debuggers like FireBug

2. Add your own javascript after the first div tag and put in a debugger; statement

 

Additional script code that gets called after the page is rendered can be added with call below AddPostRenderCallback, original script and this are added immediately after first div tag

<!–#_
AddPostRenderCallback(ctx, function()
{
//code to execute
});
_#–>

 

To get the client context from the JavaScript use as this may be needed to make additional CSOM calls

Srch.ScriptApplicationManager.get_clientRuntimeContext().

 

If there are other scripts that you need to load in your display templates you can use the EnsureScriptFunc method, like this: EnsureScriptFunc("sp.js", "SP.ClientContext", function () { //callback });

Advertisements
Categories: SP 2013 Tags: ,
  1. No comments yet.
  1. July 3, 2014 4:24 pm at 4:24 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: