Проблема с обрезанными заголовками на странице результатов поиска в Sharepoint 2013

Во время разработки search-driven сайта на Sharepoint 2013 мы столкнулись со следующей проблемой: для некоторых страниц заголовки были обрезаны в результатах поиска:

image

Т.е. для большинства страниц заголовки отображались нормально, но для некоторых они обрезались, как показано на примере выше (“Find the right solution” –> “he right”, “We as business partner” –> “as busine”, …). Эти заголовки не совсем такие, как в реальном сайте, но они хорошо иллюстрируют проблему. При этом не было очевидного общего признака для страниц, заголовки которых обрезались: для некоторых страниц отображалось несколько полных слов из заголовка, для других слова были обрезаны и ключевые слова, использованные для поиска не показывались.

Исследование показало, что проблема в стандартном шаблоне отображения (display template) Item_CommonItem_Body.html. Заголовок отображается с помощью следующего кода:

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

Т.е. сначала получаем выделенные заголовки с помощью метода Srch.U.getHighlightedProperty() (строка 1), и затем делаем тримминг для добавления в ссылку с помощью метода Srch.U.trimTitle() (строка 8). Сначала я подумал, что метод trimTitle работает неправильно по какой-то причине. Он, как и метод getHighlightedProperty, определен в файле Search.ClientControls.js, расположенном в папке /15/Template/Layouts. Я добавил в Item_CommonItem_Body.html временные трейсы, которые показали, что обрезанные заголовки возвращаются из getHighlightedProperty. Вот код этого метода:

Srch.U.getHighlightedProperty =
function Srch_U$getHighlightedProperty(key, result, property) {
    var $v_0 = null;
    if (!Srch.U.e(key)) {
        if (!((key) in Srch.ScriptApplicationManager.get_current().$23_1)) {
            Srch.ScriptApplicationManager.get_current().$23_1[key] =
                Srch.U.$5H(result['HitHighlightedProperties']);
        }
        var $v_1 = Srch.ScriptApplicationManager.get_current().$23_1[key];
        if (!Srch.U.n($v_1)) {
            if (property === 'Title') {
                property = 'HHTitle';
            }
            else if (property === 'Path') {
                property = 'HHUrl';
            }
            else {
                property = property.toLowerCase();
            }
            $v_0 = $v_1[property];
        }
    }
    return $v_0;
}

Параметр key содержит идентификатор элемента, который отображается в результатах поиска, result – ctx.CurrentItem, и property в нашем случае содержит “Title”. Исследование показало, что он доходит до строки 12 (property = ‘HHTitle’) и затем читает свойство “HHTitle” из объекта, который возвращается из следующего вызова: Srch.U.$5H(result[‘HitHighlightedProperties’]) (строки 6-7). Т.е. проблема вызвана неправильным вычислением выделенных заголовков, записанных в ctx.CurrentItem[‘HitHighlightedProperties’].

Тесты также показали, что языковые установки браузера влияют на результат, т.е. заголовки могут обрезаться для одного языка, но показываться правильно для другого. В качестве обходного пути для этой проблемы, можно скопировать шаблон отображения Item_CommonItem_Body.html и изменить его код на следующий:

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

Т.е. использовать $htmlEncode(ctx.CurrentItem.Title), который возвращает исходный неизмененный заголовок, вместо выделенного. После этого надо указать этот шаблон отображения в свойствах веб части ResultScriptWebPart, которая отображает результаты поиска. Но с этим решением ключевые слова, использованные для поиска, не будут выделяться в заголовках.

Описанная проблема выглядит как баг в компонентах поиска. Если вы столкнулись с ней или нашли другое решение, то опишите его в комментариях.

Реклама

Об авторе sadomovalex

Старший инженер, team lead, консультант. Работаю в стеке .Net. Последние несколько лет занимаюсь разработкой enterprise приложений под Sharepoint, чему и будет в основном посвящена тематика этого блога. Также активно использую и интересуюсь ASP.Net MVC, DDD, TDD, Agile. Активно участвую в жизни многих профессиональных сообществ, SPb .Net UG, SPb ALT.Net, rsdn, Finland SP UG и др.
Запись опубликована в рубрике Search, Sharepoint. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s