Saturday, September 7, 2013

Problem with cut titles in search results in Sharepoint 2013

During implementation of search-driven site on Sharepoint 2013 we faced with the following problem: for some pages titles were cut on search results page:

image

I.e. for most pages titles were ok, but for some of them they were cut as shown on the picture above, e.g. “Find the right solution” were cut to “he right”, “We as business partner” to “as busine”, etc. These titles are not exactly the same as on the real site, but they should show the basic problem. There were no visible consistent pattern for the cutting: for some titles several full words were included, for another words were cut and shown part didn’t contain the keywords added by user in the search box.

Investigation showed that the problem comes from standard Item_CommonItem_Body.html display template. Title is shown with the following code inside it:

   1: var title = Srch.U.getHighlightedProperty(id, ctx.CurrentItem, "Title");
   2: ...
   3: var titleHtml = String.format(
   4: '<a clicktype="{0}" id="{1}" href="{2}" class="ms-srch-item-link" ' +
   5: 'title="{3}" onfocus="{4}" {5}>{6}</a>',
   6: $htmlEncode(clickType), $htmlEncode(id + Srch.U.Ids.titleLink), $urlHtmlEncode(url),
   7: $htmlEncode(ctx.CurrentItem.Title), showHoverPanelCallback, appAttribs,
   8: Srch.U.trimTitle(title, maxTitleLengthInChars, termsToUse));
   9: ...
  10: <div id="_#= $htmlEncode(id + Srch.U.Ids.title) =#_" class="ms-srch-item-title"> 
  11:     <h3 class="ms-srch-ellipsis">
  12:         _#= titleHtml =#_
  13:     </h3>
  14: </div>

I.e. at first it gets the highlighted title using Srch.U.getHighlightedProperty() method (line 1), and then trims it for adding into the “a” tag using Srch.U.trimTitle() method (line 8). The first thing which came to my mind was that trimTitle method worked incorrectly. This method (as well as getHighlightedProperty) is defined in Search.ClientControls.js file, which is located in 15/template/layouts folder. I added temporary traces into it using console.log and found that wrong title is returned already from getHighlightedProperty method. Here is the code of this method:

   1: Srch.U.getHighlightedProperty =
   2: function Srch_U$getHighlightedProperty(key, result, property) {
   3:     var $v_0 = null;
   4:     if (!Srch.U.e(key)) {
   5:         if (!((key) in Srch.ScriptApplicationManager.get_current().$23_1)) {
   6:             Srch.ScriptApplicationManager.get_current().$23_1[key] =
   7:                 Srch.U.$5H(result['HitHighlightedProperties']);
   8:         }
   9:         var $v_1 = Srch.ScriptApplicationManager.get_current().$23_1[key];
  10:         if (!Srch.U.n($v_1)) {
  11:             if (property === 'Title') {
  12:                 property = 'HHTitle';
  13:             }
  14:             else if (property === 'Path') {
  15:                 property = 'HHUrl';
  16:             }
  17:             else {
  18:                 property = property.toLowerCase();
  19:             }
  20:             $v_0 = $v_1[property];
  21:         }
  22:     }
  23:     return $v_0;
  24: }

key parameter passed to this method is the id of the item shown in the search results, result is ctx.CurrentItem and property in our case is “Title”. Using traces I checked that it goes to line 12 (property = 'HHTitle') and then reads property “HHTitle” from object, which is returned from the following call: Srch.U.$5H(result['HitHighlightedProperties']) (lines 6-7). I.e. the problem is caused by incorrect calculation of the highlighted title stored in ctx.CurrentItem[‘HitHighlightedProperties’].

Test showed that current browser language affects this method, i.e. title may be cut for one language, but shown properly for another. As a workaround for this problem you may change the code of Item_CommonItem_Body.html display template to the following:

   1: '<a clicktype="{0}" id="{1}" href="{2}" class="ms-srch-item-link" ' +
   2: 'title="{3}" onfocus="{4}" {5}>{3}</a>',
   3: $htmlEncode(clickType), $htmlEncode(id + Srch.U.Ids.titleLink), $urlHtmlEncode(url),
   4: $htmlEncode(ctx.CurrentItem.Title), showHoverPanelCallback, appAttribs);

I.e. use $htmlEncode(ctx.CurrentItem.Title) which shows original title, instead of highlighted title. However with this approach your titles won’t be highlighted anymore.

This behavior looks like a bug in search components. If you faced with the same problem or if you know another solutions and what causes it, please share it in comments.

2 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete