SharePoint 2013 アイテム表示テンプレートを使用して検索結果の表示をカスタマイズする

こんにちは、SharePoint サポートの佐伯です。
今回の投稿では、アイテム表示テンプレートを使用して検索結果の表示をカスタマイズする方法についてご紹介します。表示テンプレートとは、検索結果で表示する情報やデザインを定義したものです。この表示テンプレートを編集して検索結果に適用することで、検索結果の表示をカスタマイズすることができます。表示テンプレートの概要については、前回の投稿をご参照ください。

今回は、下の画像のように検索結果のアイテムのタイトルサマリー更新者最終更新日時URL を表示するアイテム表示テンプレートを作成してみましょう。

アイテム表示テンプレート (*.html) の作成
それでは実際に、アイテム表示テンプレートを作成してみましょう。既存の表示テンプレートをコピーして作成すると簡単です。 SharePoint 既定のアイテム表示テンプレート “既定のアイテム” をもとに、アイテム表示テンプレートを作成しましょう。
なお、*.html ファイルは発行インフラストラクチャをアクティブにしている場合のみ作成できます。この投稿では、発行インフラストラクチャをアクティブにしたサイトで *.html ファイルを作成する方法をご紹介します。
1. [サイトの設定] - [Web デザイナー ギャラリー] - [マスター ページ] をクリックし、マスター ページ ギャラリーを開きます。
2. [Display Templates]、[Search] の順にフォルダを展開し、Item_Default.html ファイルをダウンロードします。

3. ダウンロードした Item_Default.html ファイルのファイル名を変更します。ここでは、Item_Custom.html に変更します。
4. Item_Custom.html ファイルを開き、<body> タグの直後にある <div> の id に、この *.html ファイルのファイル名を記述します。
<body>
    <div id="Item_Custom">

5. <title> には表示テンプレートのタイトルを入力します。
<title>カスタム アイテム</title>

6. <mso:MasterPageDescription> には表示テンプレートの説明を記述します。
<mso:MasterPageDescription msdt:dt="string">結果アイテムのタイトル、サマリー、更新者、最終更新日時、URL を表示します。</mso:MasterPageDescription>

7. 検索結果に表示する管理プロパティのマッピング (タイトル、サマリー、更新者、最終更新日時、URL) を設定します。
<mso:ManagedPropertyMapping msdt:dt="string">
'Title':'Title','Path':'Path','EditorOWSUSER':'EditorOWSUSER','LastModifiedTime':'LastModifiedTime',
'HitHighlightedSummary':'HitHighlightedSummary'
</mso:ManagedPropertyMapping>

(補足) 管理プロパティのマッピングを追加する際は、‘<変数名>’:’<管理プロパティ名>’ と記述します。この <変数名> と <管理プロパティ名> は可能な限り同じ名称にすることをおすすめします。
もし、<変数名> を <管理プロパティ名> と異なるものに指定する際は、本投稿の下部に記載している 補足) アイテムの情報を取得し表示する Javascript コードの記述方法 をご確認ください。

8. <body> 内に、アイテムのタイトル、サマリー、更新者、最終更新日時、URL を取得する Javascript コードを記述します。
<!--#_
    //タイトルを取得します。
    var title = ctx.CurrentItem.Title;
    var titleHtml = String.format('<a href="{0}" title="{1}" >{2}</a>', $urlHtmlEncode(ctx.CurrentItem.Path), $htmlEncode(title), $htmlEncode(title));

    //URL を取得します。
    var pathHtml = ctx.CurrentItem.Path;

    //サマリーを取得します。
    var summaryHtml = Srch.U.processHHXML(ctx.CurrentItem.HitHighlightedSummary);

    //最終更新日時を取得します。
    var lastModifiedTime = ctx.CurrentItem.LastModifiedTime;
    var lastModifiedTimeHtml = "最終更新日時 " + lastModifiedTime.getFullYear() + "年" + (lastModifiedTime.getMonth() + 1) + "月" + lastModifiedTime.getDate() +"日";

    //更新者を取得します。
    var editorHtml = "";
    if (!$isEmptyString(ctx.CurrentItem.EditorOWSUSER)){
        var editorIdentifiers = ctx.CurrentItem.EditorOWSUSER.split(" | ");
             if(!$isNull(editorIdentifiers[1]))
             {
                 editorHtml = "更新者 " + editorIdentifiers[1];
             }
    }
_#-->

9. 表示するアイテムの情報をタイトル、サマリー、更新者、最終更新日時、URL に変更するため、アイテム表示テンプレート “既定のアイテム” でアイテムの情報を表示していた以下のコードを削除します。
_#=ctx.RenderBody(ctx)=#_

10. 手順 8 の Javascript コードの後ろに、アイテムのタイトル、サマリー、更新者、最終更新日時、URL を表示するコードを記述します。
<h3 class="ms-srch-ellipsis">_#=titleHtml=#_</h3><!-- タイトル -->
<div class="ms-srch-item-path">_#=pathHtml=#_</div><!-- URL -->
<div class="ms-srch-item-summary">_#=summaryHtml=#_</div><!-- サマリー -->
<div>
<span>_#=lastModifiedTimeHtml=#_</span><!-- 最終更新日時 -->
<span>_#=editorHtml=#_</span><!-- 更新者-->
</div>

手順 8、10 で記載している Javascript コードについては、本投稿の下部に記載している 補足) アイテムの情報を取得し表示する Javascript コードの記述方法 をご参照ください。

11. Item_Custom.html ファイルを保存します。これでアイテム表示テンプレートの作成は完了です。
Item_Custom.html ファイルは下記のようになります。
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<title>カスタム アイテム</title>

<!--[if gte mso 9]><xml>
<mso:CustomDocumentProperties>
<mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden>
<mso:MasterPageDescription msdt:dt="string">結果アイテムのタイトル、サマリー、更新者、最終更新日時、URL を表示します。</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','EditorOWSUSER':'EditorOWSUSER','LastModifiedTime':'LastModifiedTime',
'HitHighlightedSummary':'HitHighlightedSummary'
</mso:ManagedPropertyMapping>
</mso:CustomDocumentProperties>
</xml><![endif]-->
</head>
<body>
    <div id="Item_Custom">
<!--#_
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();
_#-->

<!--#_
    //タイトルを取得します。
    var title = ctx.CurrentItem.Title;
    var titleHtml = String.format('<a href="{0}" title="{1}" >{2}</a>', $urlHtmlEncode(ctx.CurrentItem.Path), $htmlEncode(title), $htmlEncode(title));

    //URL を取得します。
    var pathHtml = ctx.CurrentItem.Path;

    //サマリーを取得します。
    var summaryHtml = Srch.U.processHHXML(ctx.CurrentItem.HitHighlightedSummary);

    //最終更新日時を取得します。
    var lastModifiedTime = ctx.CurrentItem.LastModifiedTime;
    var lastModifiedTimeHtml = "最終更新日時 " + lastModifiedTime.getFullYear() + "年" + (lastModifiedTime.getMonth() + 1) + "月" + lastModifiedTime.getDate() +"日";

    //更新者を取得します。
    var editorHtml = "";
    if (!$isEmptyString(ctx.CurrentItem.EditorOWSUSER)){
        var editorIdentifiers = ctx.CurrentItem.EditorOWSUSER.split(" | ");
             if(!$isNull(editorIdentifiers[1]))
             {
                 editorHtml = "更新者 " + editorIdentifiers[1];
             }
    }
_#-->

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

         <h3 class="ms-srch-ellipsis">_#=titleHtml=#_</h3><!-- タイトル -->
         <div class="ms-srch-item-path">_#=pathHtml=#_</div><!-- URL -->
         <div class="ms-srch-item-summary">_#=summaryHtml=#_</div><!-- サマリー -->
         <div>
                  <span>_#=lastModifiedTimeHtml=#_</span><!-- 最終更新日時 -->
                  <span>_#=editorHtml=#_</span><!-- 更新者-->
         </div>

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

- 表示テンプレート ファイルのアップロードと適用
1. 作成した Item_Custom.html ファイルをマスター ページ ギャラリーにアップロードします。
2. アップロード後のプロパティの編集画面で、アイテム表示テンプレート (*.html) の作成手順 4 ~ 7 で記述した設定が反映されていることを確認し、保存します。
3. 検索結果 Web パーツを配置したページを開き、ページ右上の [ページの編集] をクリックします。
4. 検索結果 Web パーツの [Web パーツの編集] をクリックします。
5. [アイテム表示テンプレート] で、作成した表示テンプレート "カスタム アイテム" を選択します。
(補足) 今回の投稿では、すべての検索結果の種類に対して、今回作成したアイテム表示テンプレートを適用します。 6 ページを保存します。
それでは検索ボックスに検索キーワードを入力し、検索をしてみましょう!

検索結果にアイテム表示テンプレートで編集した内容が反映されました!!

補足) アイテムの情報を取得し表示する Javascript コードの記述方法
表示テンプレートでは、Javascript でアイテムの情報を取得し、表示します。まずは以下の記述方法を押さえておきましょう。

<!--#_ Javascript コード _#--> タグ内に Javascript コードを記述
_#= =#_ 式の結果を HTML の中に出力する

<例 1>
上記の 2 点の記述方法について、以下のサンプル コードを例に説明します。
以下のコードでは、変数 text に "Sample" という文字列をセットし、変数 text の結果を HTML の中に出力します。

<!--#_ var text = "Sample"; _#-->
<div style="color:#4169e1">_#=text=#_</div>

HTML での出力結果は以下となります。

<例 2>
実際にアイテムのプロパティを取得し、出力する方法について見ていきましょう。
ctx.CurrentItem は検索結果のアイテムのオブジェクトです。このオブジェクトから対象のプロパティを取得します。アイテムのタイトルを取得したい場合は、ctx.CurrentItem.Title または $getItemValue(ctx, "Title") と記述します。

<!--#_ var title = ctx.CurrentItem.Title; _#-->
<span>_#=title=#_</span>

または、

<!--#_ var title = $getItemValue(ctx, "Title"); _#-->
<span>_#=title=#_</span>

HTML での出力結果は以下となります。

※なお、ここで取得するプロパティは、<mso:ManagedPropertyMapping> で管理プロパティのマッピングの設定をしておく必要があります。また、管理プロパティのマッピング ‘<変数名>’:’<管理プロパティ名>’ で、<変数名> を <管理プロパティ名> と異なる名称に設定している場合は、$getItemValue(ctx, "<変数名>") でアイテムのプロパティを取得します。
例)
<mso:ManagedPropertyMapping>’DisplayTitle’:’Title’</mso:ManagedPropertyMapping>

<!--#_ var title = $getItemValue(ctx, "DisplayTitle"); _#-->
<span>_#=title=#_</span>

今回の投稿は以上です。

検索のカスタマイズや設定に関する過去の投稿もご参考にしていただけますと幸いです。
SharePoint 2013 検索の設定やカスタマイズに関する投稿まとめ