Wednesday, May 23, 2012

Customize Search Results in SharePoint 2010 – only show documents in search result.

After configuring the Search Service Application and completion of the crawl, now it was the time for search results. My requirement was to show only documents in the search result. The option were

1.     Configure the search scope

2.     Remove file types – from crawl

3.     Customize the search core result webpart.

I took the last option since I am using a custom branding for my site and I cannot let the user to navigate to the out of the box pages.

The steps are very easy, except the xslt modification. I modified the xslt for the search result webpart from the help from the sites mentioned in reference section. Combining and putting some custom logic I could achieve the solution.

My xslt shows the result in a tabular view and only documents such as doc, docx, ppt.. etc.

The magic xslt is below: Smile

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">

  <xsl:output method="html" indent="no"/>

  <xsl:param name="dvt_adhocmode">sort</xsl:param>

  <xsl:decimal-format NaN=""/>

 

  <xsl:param name="FileName" />

  <xsl:param name="dvt_apos">'</xsl:param>

  <xsl:param name="dvt_fieldsort" />

  <xsl:param name="dvt_filterfield" />

  <xsl:param name="dvt_sortdir">ascending</xsl:param>

  <xsl:param name="dvt_sortfield" />

  <xsl:param name="dvt_sorttype">text</xsl:param>

  <xsl:param name="dvt_filterfields" />

  <xsl:param name="dvt_partguid" />

 

  <xsl:param name="AlertMeLink" />

  <xsl:param name="AlertMeText" />

  <xsl:param name="ShowMessage" />

  <xsl:param name="ShowActionLinks" />

  <xsl:param name="SrchRSSText" />

  <xsl:param name="SrchRSSLink" />

  <xsl:param name="SearchProviderText" />

  <xsl:param name="SearchProviderLink" />

  <xsl:param name="SearchProviderAlt"/>

 

  <xsl:param name="ResultsNotFound" />

  <xsl:param name="NoResultsSuggestion" />

  <xsl:param name="NoResultsSuggestion1" />

  <xsl:param name="NoResultsSuggestion2" />

  <xsl:param name="NoResultsSuggestion3" />

  <xsl:param name="NoResultsSuggestion4" />

  <xsl:param name="NoResultsSuggestion5" />

  <xsl:param name="AdditionalResources" />

  <xsl:param name="AdditionalResources1" />

  <xsl:param name="AdditionalResources2" />

  <xsl:param name="IsSearchServer" />

  <xsl:param name="Period" />

  <xsl:param name="SearchHelp" />

  <xsl:param name="Tags" />

  <xsl:param name="Keyword" />

 

 

  <xsl:variable name="dvt_1_automode">0</xsl:variable>

<!-- XSL transformation starts here -->

  <xsl:template match="/">

    <xsl:choose>

      <xsl:when test="$ShowMessage = 'True'">

        <xsl:call-template name="dvt_1.empty" />

      </xsl:when>

      <xsl:otherwise>

        <xsl:call-template name="dvt_1"/>

        <style type="text/css">

          .ms-alternatingstrong

          {

          background-color:#e3efff;

          }

        </style>

      </xsl:otherwise>

    </xsl:choose>

   

  </xsl:template>

<!-- End XSL transformation starts here -->

  <!-- Main Table-->

  <xsl:template name="dvt_1">

    <xsl:variable name="dvt_StyleName">Table</xsl:variable>

    <xsl:variable name="Rows" select="/All_Results/Result"/>

    <table border="0" width="93%" cellpadding="4" cellspacing="2" id="ResultsTable" align="right">

      <tr valign="top">

        <xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">

          <th class="ms-vh" width="1%" nowrap="nowrap"></th>

        </xsl:if>

        <th class="ms-vh" nowrap="">

        </th>

        <th class="ms-vh" nowrap="" style="width: 257px" align="left">

          <xsl:call-template name="dvt.headerfield" ddwrt:atomic="1">

            <xsl:with-param name="fieldname">title</xsl:with-param>

            <xsl:with-param name="fieldtitle">TITLE</xsl:with-param>

            <xsl:with-param name="displayname">TITLE</xsl:with-param>

            <xsl:with-param name="sortable">1</xsl:with-param>

            <xsl:with-param name="fieldtype">Text</xsl:with-param>

          </xsl:call-template>

        </th>

        <th class="ms-vb" nowrap="" align="left" style="font-size:11pt; font-family:Helvetica;" >

          DESCRIPTION

        </th>

        <th class="ms-vh" nowrap="" align="left">

          <xsl:call-template name="dvt.headerfield" ddwrt:atomic="1">

            <xsl:with-param name="fieldname">write</xsl:with-param>

            <xsl:with-param name="fieldtitle">PUBLISHED</xsl:with-param>

            <xsl:with-param name="displayname">PUBLISHED</xsl:with-param>

            <xsl:with-param name="sortable">1</xsl:with-param>

            <xsl:with-param name="fieldtype">Text</xsl:with-param>

          </xsl:call-template>

        </th>

      </tr>

      <xsl:call-template name="dvt_1.body">

        <xsl:with-param name="Rows" select="$Rows"/>

      </xsl:call-template>

    </table>

  </xsl:template>

  <!-- End Main Table-->

 

  <!-- Create the Table Body row-->

  <xsl:template name="dvt_1.body">

    <xsl:param name="Rows"/>

    <xsl:for-each select="$Rows">

      <xsl:sort select="*[name() = $dvt_sortfield] | @*[name() = $dvt_sortfield] | text()[name(ancestor::*[1]) = $dvt_sortfield]" order="{$dvt_sortdir}" data-type="{$dvt_sorttype}" />

      <xsl:sort select="title" order="ascending" />

      <xsl:sort select="write" order="ascending" />

        <xsl:choose>

          <xsl:when test="contains(url, 'docx') or contains(url,'doc') or contains(url,'xls') or contains(url,'xlsx') or contains(url,'ppt') or contains(url,'pdf') or contains(url,'jpg')">

            <xsl:call-template name="dvt_1.rowview"/>           

          </xsl:when>

          <xsl:otherwise>

            <xsl:text></xsl:text>

          </xsl:otherwise>

        </xsl:choose>

    </xsl:for-each>

  </xsl:template>

  <!-- End Create the Table Body row-->

 

  <!-- Create the Table Row -->

  <xsl:template name="dvt_1.rowview">

    <tr>

  <!-- Test for restrcting file types -->

      <xsl:if test="contains(url, 'docx') or contains(url,'doc') or contains(url,'xls') or contains(url,'xlsx') or contains(url,'ppt') or contains(url,'pdf') or contains(url,'jpg')">

 

        <xsl:if test="position() mod 2 = 1">

        <xsl:attribute name="class">ms-alternatingstrong</xsl:attribute>

      </xsl:if>

      <xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">

        <td class="ms-vb" width="1%" nowrap="nowrap">

          <span ddwrt:amkeyfield="" ddwrt:amkeyvalue="string($XPath)" ddwrt:ammode="view"></span>

        </td>

      </xsl:if>

      <td class="ms-vb">

        <img border="0" src="{imageurl/text()}" />

      </td>

      <td class="ms-vb" style="width: 257px">

        <a href="{url}" target="_blank">

          <xsl:value-of select="title" />

        </a>

      </td>

      <td class="ms-vb">

        <xsl:choose>

          <xsl:when test="string-length(hithighlightedsummary/text()) &lt; 80">

            <div>

              <xsl:value-of select="hithighlightedsummary/text()" />

            </div>

          </xsl:when>

          <xsl:otherwise>

            <div>

              <xsl:value-of select="substring(hithighlightedsummary/text(),1,75)" />

            </div>

            <a href="#" onclick="javascript:moreless(this,'{hithighlightedsummary}')">more&gt;&gt;</a>

          </xsl:otherwise>

        </xsl:choose>

 

        <script type="text/javascript">

          function moreless(abc,fullText)

          {

          if(abc.innerText == "more&gt;&gt;")

          {

          div = abc.parentNode.getElementsByTagName('div');

          div[0].innerText = fullText;

          abc.innerText = "&lt;&lt;less";

          }

          else if(abc.innerText == "&lt;&lt;less")

          {

          div = abc.parentNode.getElementsByTagName('div');

          div[0].innerText = fullText.substring(0,75);

          abc.innerText = "more&gt;&gt;";

          }

 

          }

        </script>

      </td>

      <td class="ms-vb">

        <xsl:value-of select="write"/>

      </td>

 

      </xsl:if>

 <!-- End Test for restrcting file types -->

    </tr>

  </xsl:template>

  <!-- End Create the Table Row -->

 

  <!-- Create the Header row-->

  <xsl:template name="dvt.headerfield">

    <xsl:param name="fieldname" />

    <xsl:param name="fieldtitle" />

    <xsl:param name="displayname" />

    <xsl:param name="sortable">1</xsl:param>

    <xsl:param name="fieldtype">0</xsl:param>

    <xsl:choose>

      <xsl:when test="($dvt_adhocmode = 'sort' or $dvt_fieldsort = '1')and $sortable='1'">

        <xsl:variable name="sortfield">

          <xsl:choose>

            <xsl:when test="substring($fieldname, string-length($fieldname) - 5) = '(text)'">

              <xsl:value-of select="substring($fieldname, 1, string-length($fieldname) - 6)" />

            </xsl:when>

            <xsl:when test="substring($fieldname, 1, 1) = '@'">

              <xsl:value-of select="substring($fieldname, 2)" />

            </xsl:when>

            <xsl:otherwise>

              <xsl:value-of select="$fieldname" />

            </xsl:otherwise>

          </xsl:choose>

        </xsl:variable>

        <xsl:variable name="linkdir">

          <xsl:choose>

            <xsl:when test="$dvt_sortfield = $sortfield and $dvt_sortdir = 'ascending'">descending</xsl:when>

            <xsl:otherwise>ascending</xsl:otherwise>

          </xsl:choose>

        </xsl:variable>

        <xsl:variable name="sortText">

          <xsl:choose>

            <xsl:when test="$linkdir='descending'">&apos; + &apos;descending&apos; + &apos;</xsl:when>

            <xsl:otherwise>&apos; + &apos;ascending&apos; + &apos;</xsl:otherwise>

          </xsl:choose>

        </xsl:variable>

        <xsl:variable name="separator" select="' '" />

        <xsl:variable name="connector" select="';'" />

        <table CtxNum="1" cellspacing="0" class="ms-unselectedtitle" onmouseover="OnMouseOverAdHocFilter(this, '{concat($displayname,$separator,$fieldname, $separator,$fieldtype, $connector, 1033, $separator, $dvt_partguid)}')">

          <tr>

            <td width="100%" class="ms-vb" nowrap="">

              <a>

                <xsl:attribute name="href">

                  javascript: <xsl:value-of select="ddwrt:GenFireServerEvent(concat('dvt_sortfield={',$sortfield,'};dvt_sortdir={',$sortText,'}'))" />;

                </xsl:attribute>

                <xsl:attribute name="onclick">

                  javascript: <xsl:value-of select="ddwrt:GenFireServerEvent(concat('dvt_sortfield={',$sortfield,'};dvt_sortdir={',$sortText,'}'))" />;

                </xsl:attribute>

                <xsl:choose>

                  <xsl:when test="$fieldtype = 'Attachments'">

                    <xsl:value-of select="$fieldtitle" disable-output-escaping="yes" />

                  </xsl:when>

                  <xsl:otherwise>

                    <xsl:value-of select="$fieldtitle" />

                  </xsl:otherwise>

                </xsl:choose>

                <xsl:if test="$dvt_sortfield = $sortfield">

                  <xsl:choose>

                    <xsl:when test="$dvt_sortdir = 'ascending'">

                      <img border="0" alt="Ascending" src="{ddwrt:FieldSortImageUrl('Desc')}" />

                    </xsl:when>

                    <xsl:when test="$dvt_sortdir = 'descending'">

                      <img border="0" alt="Descending" src="{ddwrt:FieldSortImageUrl('Asc')}" />

                    </xsl:when>

                  </xsl:choose>

                </xsl:if>

              </a>

              <xsl:if test="contains($dvt_filterfields, concat($fieldname, ';' ))">

                <IMG SRC="/_layouts/images/filter.gif" BORDER="0" ALT="" />

              </xsl:if>

            </td>

            <td>

              <img src="/_layouts/images/blank.gif" width="13" style="visibility: hidden" alt="" />

            </td>

          </tr>

        </table>

 

      </xsl:when>

      <xsl:otherwise>

        <xsl:choose>

          <xsl:when test="$fieldtype = 'Attachments'">

            <xsl:value-of select="$fieldtitle" disable-output-escaping="yes" />

          </xsl:when>

          <xsl:otherwise>

            <xsl:value-of select="$fieldtitle" />

          </xsl:otherwise>

        </xsl:choose>

      </xsl:otherwise>

    </xsl:choose>

    <xsl:if test="$dvt_filterfield=$fieldname" ddwrt:cf_ignore="1">

      <img alt="Filter" src="{ddwrt:FieldFilterImageUrl('')}" />

    </xsl:if>

  </xsl:template>

  <!-- End of Create the Header row-->

 

  <!-- When empty result set is returned from search -->

  <xsl:template name="dvt_1.empty">

    <div class="srch-results" accesskey="W">

      <span class="srch-description2" id="CSR_NO_RESULTS">

        <p>

          <xsl:value-of select="$ResultsNotFound" />

          <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>

          <strong>

            <xsl:value-of select="$Keyword" />

          </strong>

          <xsl:value-of select="$Period" />

        </p>

        <h3>

          <xsl:value-of select="$NoResultsSuggestion" />

        </h3>

        <ul>

          <li>

            <xsl:value-of select="$NoResultsSuggestion1" />

          </li>

          <xsl:if test="string-length($NoResultsSuggestion4) &gt; 0">

            <li>

              <xsl:value-of select="$NoResultsSuggestion4" />

            </li>

          </xsl:if>

          <xsl:if test="string-length($NoResultsSuggestion5) &gt; 0">

            <li>

              <xsl:value-of select="$NoResultsSuggestion5" />

            </li>

          </xsl:if>

        </ul>

        <h3>

          <xsl:value-of select="$AdditionalResources" />

        </h3>

        <ul>

          <li>

            <xsl:value-of select="$AdditionalResources2" />

          </li>

        </ul>

 

      </span>

    </div>

  </xsl:template>

  <!-- End When empty result set is returned from search -->

 

</xsl:stylesheet>

 

 

The output looks like below:

clip_image002[4]

 

There are lot of places could further be modified as per your requirements. I have kept the xslt with comments for easy understanding. Don’t ask me each and every line, I am not a master in xslt though. I am sure this will help a lot of people struggling with modifying search result.

 

Thanks for reading…

 

If you have a more elegant solution/suggestion – please post a comment… I’ll be happy to hear.


...HaPpY CoDiNg

Partha (Aurum)

 

Ref:

http://sharepoint2010search.codeplex.com/documentation

http://msdn.microsoft.com/en-us/library/ms584121(v=office.12).aspx

http://msdn.microsoft.com/en-us/library/ms546985(v=office.12).aspx

http://sharepointmalarkey.wordpress.com/2011/01/31/search-core-results-web-part-how-to-view-raw-xml/

http://technet.microsoft.com/en-us/library/gg549987.aspx

http://msdn.microsoft.com/en-us/library/ms546985.aspx

http://www.sharemuch.com/2010/06/17/excluding-sharepoint-2010-search-results-of-certain-file-types/

 

No comments:

Post a Comment