Friday, July 14, 2017

Adding custom managed properties to the default display templates – the quick and dirty way for non-developers with little time on their hands

Yesterday I was helping another consultant with some search rank issues. We had an hour scheduled and managed to resolve the ranking well enough. But then I got the question, do we have time to add some custom data to the results? Ouch! Something which sounds easy, and is not done in 5 minutes. Turns out after I gave it some thought on an upset stomach due to a bad kebab yesterday, it is actually a 5 min task when you know how.

Read on!

The search page was a typical custom search page created in a team site as a web part page, with three search web parts and a scoped query. Very easy to set up in a few minutes. The results were Office documents and PDF’s scoped to a few specific locations.

image

There are numerous posts out there on how to add custom managed properties, but that involves duplicating all the default display templates, or creating a mother of all template which renders all file types the way you want.  If you try to modify one of the default display templates to add your custom managed property, it just won’t load.

So why this post? Well, I’ll let you know how you indeed can modify the default templates, and still get your custom managed property to render. It might not be the proper or recommended way, but it works and will save non-devs tons of time making minor changes to the search results.

A typical result looks like the image below, and we want to add some piece of metadata at the red arrows.

imageShow me how already, will you!

Start off with downloading a copy of Item_CommonItem_Body.js from /_catalogs/masterpage/display%20templates/search/item_commonitem_body.js in your site collection. This is a shared template used by all the other ones.

Around line 120 (at least on my recent download), add the code to show after the path in green. As my example I’m adding values from a managed property named encoding, which is not one of the default ones available in the results. I do this my adding the highlighted line below:

ms_outHtml.push('       '
,'            <div id="', $htmlEncode(id + Srch.U.Ids.preview) ,'" class="ms-srch-item-previewContainer"> '
,'                ', previewHtml ,''
,'            </div>'
);
        }
        
        ms_outHtml.push('Encoding:' + $getItemValue(ctx, "encoding"));
        
ms_outHtml.push(''
,'    '
);

Upload the updated Item_CommonItem_Body.js, overwriting your existing one. Make sure it’s published.

Your results will now show the label, but no value for encoding.

image

So how do you ensure loading of your custom properties? Basically you modify a web part property called SelectedPropertiesJson on the search result web part. You can download the .webpart file and modify it manually, or you can for example use PnP PowerShell.

image

The below code ensures loading of two managed properties, encoding and refinablestring100.

Connect-PnPOnline -Url https://tenant.sharepoint.com/sites/searchsite

$webPartName = "Search Results"
$pageUrl = "/sites/test2/SitePages/My Search Page.aspx"

$wpId = (Get-PnPWebPart -ServerRelativePageUrl $pageUrl |? {$_.WebPart.Title -eq $webPartName}).Id
$myProps = @("encoding","refinablestring100")
$json = ConvertTo-Json $myProps -Compress
Set-PnPWebPartProperty -ServerRelativePageUrl $pageUrl -Identity wpId -Key "SelectedPropertiesJson" -Value $json

If you refresh the search result page, it’s now also displaying your custom properties!

image

12 comments:

  1. This one makes me a little nervous (editing a default Display Template), but hey, you were delirious from a bad kebab.

    M.

    ReplyDelete
    Replies
    1. I do say it's not best practice, but I'm like..these files have not changed afaik since released way back, so for a non-dev in an isolated sitecol, why not? I believe quick and dirty might have a place until we're all modern :)

      Delete
    2. It depends. :)

      If you were to do this in the Search Center, you might be in more trouble. Of course, you're just editing a few things, which in theory can always be set back. But time and time again I tell people: DO NOT EDIT DEFAULT ARTIFACTS IN SHAREPOINT. No matter how smart you are, you can screw it up and sometimes recovery is really hard - and it's almost always embarrassing.

      But what you're doing obviously works. Creating a copy of the Display Template would make it less worrisome. Since most people don't know how to get at the .webpart file, maybe we're good.

      M.

      Delete
    3. I'm all with you :) Modifying is usually bad. Doing a proper display template setup is for most people too complex (unfortunately). And time will tell if I'll deploy this myself ;)

      Delete
  2. Hi Mike,

    ‪I have expanded the Item_Person display template to include a couple of custom managed properties. When this template is used in person-only search these properties gets data. However when I add a result block in a everything search, the property gets no data. Any suggestions??‬

    How CA I get the properties displayed in both people search and everything search?

    Thanks,
    Muthu

    ReplyDelete
    Replies
    1. I suggest doing it proper. Copy the template, add your prop the right way, create a result type for the prop, and force use that type in the block. And remember to check "optimize for frequent use" on the result type.

      Delete
  3. Thank you Mikael, I like being famous. ;-)
    This makes sense, and I take your (and @sympmarc's) cautions to heart.
    I will try the js/webpart mod tonight when the users are off so I can hack it back together if required.
    Thanks again!
    Gerry

    ReplyDelete
    Replies
    1. Working on this, I was unable to edit the "Item_CommonItem_Body.js" because it is associated with a HTML file of the same name.

      Delete
    2. That means you have publishing activated, and should edit the html file, which will convert to a .js file on upload. The edit is slightly different, but you might be able to work it out..as you don't need the ms_outhtml.push lines...those are part of the auto conversion.

      Delete
  4. Hi Mikael,

    Nice post!
    I want to add custom property in hover panel of all types of documents. Modifying the default Item_default and Item_Default_HoverPanel template not showing the property value after publishing. Is there any caching time? (works when there is custom template)

    ReplyDelete
    Replies
    1. Hi, if using this you only would need to change the hover file. Just make sure you don't change search settings in the wp in the UI after you set the property, as it will be cleared out. And if you have pub enabled, edit the .html file and not the .js file.

      Delete
    2. ...and Anuja, you're a dev, so you have the skills and time to do it proper :)

      Delete