Monday, February 23, 2015

Managed property mapping retrieval in a Display Template explained

If you read this you have most likely created a custom display template one time or another, and also used a custom managed property in that template.

Understanding the relationship with managed properties and display templates is quite useful when you construct your own template logic. At the end I will also cover the relationship between a display template and the search engine.

Lesson learned: After reading this post you should have learned that when in doubt, use $getItemValue(ctx, "Variable Name") and not ctx.CurrentItem.ManagedPropertyName.
Managed property mappings all resides in the <mso:ManagedPropertyMapping> node in the header of your display template. Here’s a sample from Item_Pictures3Lines.html.

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

Let’s break it down a bit, and the first part illustrates the relationship pretty good.

'Picture URL':'PublishingImage;PictureURL;PictureThumbnailURL'

The first part before the colon (green) is a display template variable name. The second part after the colon (yellow) is a semi-colon separated list of managed property names.

What this means is that if you use $getItemValue(ctx, “Picture URL”).value, you will get the value from the managed property PublishingImages, IF IT CONTAINS A VALUE. If not, then it will check if PictureURL contains a value, and if not, lastly check if PictureThumbnailURL contains a value.

Basically what you have is a fallback list of managed properties to use for that variable. Another sample taken from Elio Struyf’s tip #7 is ‘location’:’country;region;city’. Show country first, if not present show region, and lastly fall back to city.

If you however use ctx.CurrentItem.PublishingImage, you access the value of that specific managed property only. Often you will see this mapping in display templates:

Here the variable and managed property have the same name, so both $getItemValue and ctx.CurrentItem will yield the same value (for most cases anyways – again read Elio’s tip #7).

If you move further down the mapping list you see 'SecondaryFileExtension','ContentTypeId'. These are plain and simple managed properties you want to use in your display template without mapping them to a display template variable name. However, you can still use $getItemValue with the managed property name for it, as the function will first try to use variable names, and fallback to managed property names.

Another use case is if you are using one of the re-usable managed properties like RefinableString00. It’s more readable in your display template if you map it to a good variable name, Then again, you might already have an alias on the managed property, which you can also use.

In the sample below I have an alias on my managed property with a custom prefix. Using a variable name with space in it is even more readable, so I go with that.

RefinableString00 –> Alias PZLLastname

Last name’:’PZLLastname

$getItemValue( ctx, “Last name”).value

The search part

If you navigate over to the Master Page gallery and look at the item properties for Item_Picture3Lines.js (the converted version of the .html file) you see the property mappings are pulled into a separate field.


When executing a search query all the managed properties are pulled out from this list and passed along as part of the data you want returned on a query. If you are searching from a search result page and not content by search web part, the managed property names are actually copied over to the corresponding Result Type, which is used to specify which managed properties to retrieve. You can see the code for this in my post The 100% way of automatically updating Result Types.

A lot of movable parts for sure, but understanding the role of managed property mappings is quite useful. And if you like to optimize, remove property mappings which you don’t use in your template. No need to pull back data you are not using :-)