Friday, December 6, 2013

SharePoint 2010 Search - View Properties Link w/ folder and case support - Federated

Issue
  • You have SharePoint 2010 Server Standard or Enterprise
  • SharePoint search results provide a link to the document, but no other links
    • Often times a user has to copy and paste the document library url into the address bar and then search for the document in the library to view the properties or kick off a workflow.  This is extremely inconvenient.
  • You would also like a link to the document's View Item (DispForm.aspx) form
  • You would also like a link to the document's Document Library
  • You would like to configure this at the Search Service level so that the links appear in any search center in the farm utilizing the Search Service and also on the OSSSearchResults pages
  • Utilizing code from the following blogs

Solution
  • Configure the Search Service in Central Administration as follows
  • IMPORTANT
    • Xslt variables and parameters are case sensitive
    • Make sure instructions are followed exactly as written
  • Create 2 managed properties (Metadata Properties in Search Service Application) after your sites have been crawled
    • basic4
      • map to basic:4(text)

        • You have to page to the right after selecting the "basic" group.  It does not show up on the first screen when searching for the crawled properties.  You cannot use the free-text search filter to find this item.
    • listitemid
      • map to ows_ID(integer)
    • Configure Federated Locations in Search Service Application.
      • Click "Local Search Results"
      • Expand "Display Information"
      • Modify the following "Core Search Results Display Metadata" sections
        • Uncheck "Use Default Formatting"
        • Add the following columns to the "Properties" window

          <Column Name="ServerRedirectedURL"/>

          <Column Name="listitemid"/>
          <Column Name="basic4"/>
           
      • Copy the contents of the XSL into a text editor like Visual Studio or Notepad  
        • Find the IsDesignMode parameter and modify as follows

          <xsl:param name="IsDesignMode">True</xsl:param>

          <xsl:param name="listitemid" />
          <xsl:param name="basic4" />
           
      • Find the DisplaySize template call and modify as follows

        <xsl:call-template name="DisplaySize">
        <xsl:with-param name="size" select="size" />
        </xsl:call-template>


        <xsl:call-template name="DisplayViewPropertiesLink">
        <xsl:with-param name="basicFour" select="basic4" />
        <xsl:with-param name="itemUrl" select="url" />
        <xsl:with-param name="siteUrl" select="sitename" />
        <xsl:with-param name="listItemId" select="listitemid" />
        <xsl:with-param name="contentclass" select="contentclass" />
        </xsl:call-template>

        <img style="display:none;" alt="" src="/_layouts/images/blank.gif"/>

      • Find the end of Stylesheet tag at bottom of document and modify as follows

        <!-- A custom template to display a link to view the properties for a document -->
        <xsl:template name="DisplayViewPropertiesLink">
        <xsl:param name="basicFour" /> <xsl:param name="itemUrl" /> <xsl:param name="siteUrl" /> <xsl:param name="listItemId" /> <xsl:param name="contentclass" /> <!-- Variables to convert siteUrl to lower -->
        <xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" />
        <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
        <xsl:if test="$contentclass='STS_ListItem_DocumentLibrary'">
        <xsl:choose>
        <xsl:when test="contains($basicFour,'http')">
        <xsl:variable name="library" select="substring-before(concat(substring-after(translate($siteUrl, $uppercase, $smallcase), concat(translate($basicFour, $uppercase, $smallcase), '/')), '/'), '/')" />
        <xsl:variable name="viewPropUrl" select="concat($basicFour, '/', $library, '/Forms/DispForm.aspx?id=', $listItemId)" />
        - <a href="{$viewPropUrl}">View Properties</a>
        </xsl:when>
        <xsl:otherwise>
        <xsl:variable name="docLibLoc" select="substring-before(substring-after($itemUrl, concat($siteUrl, '/')), '/')" />
        <xsl:variable name="viewPropUrl" select="concat($siteUrl, '/', $docLibLoc, '/Forms/DispForm.aspx?id=', $listItemId)" />
        - <a href="{$viewPropUrl}">View Properties</a>
        </xsl:otherwise>
        </xsl:choose>
        </xsl:if>
        - <a href="{$siteUrl}">
        View Library
        </a>
        </xsl:template>

        <!-- End of Stylesheet -->
        </xsl:stylesheet>

         
      • Copy the contents of the text file into the "Properties:" textbox, replacing all existing text
      • Hit OK to save the changes
    • You may need to reset the index and run a full crawl to get everything working afterwards
      • Sometimes the Search Centers cache the old XSLT for awhile, so the index reset and possibly an app pool recycle may get it to refresh from the federated location.  Or toggling the Core Results web part on the search center page can work as well.


    15 comments:

    1. Hi Robert,

      thank you for this post, but there is still an issue on "view properties" link with documents in folders and subfolders like :
      /someLibrary/someFolder/someSubFolder/someFile.abc
      Do you have the fix ?

      Christophe

      ReplyDelete
      Replies
      1. Hi Christophe,

        In my tests this handles subfolders within a folder. Can you post the url you are getting for the "View Properties" link.

        Delete
    2. Hi Robert,

      thank you very much for this blog.
      This is the one and only working step-by-step instruction to make the sharepoint 2010 search really useful.
      I wasted hours before I found this.

      Stefan

      ReplyDelete
    3. is it possible for this to work with a tabular view?

      ReplyDelete
      Replies
      1. These links can be moved to anywhere within your template. You would just need to move the call-template section to the appropriate location (within a table column for example).

        Example of a tabular xstl template may be found here: http://sharepoint2010search.codeplex.com/

        Delete
    4. Thanks! Been fighting with this for a while before I found your solution. One thing, Is there a way to open them in the dialog or set the document referrer? When you close the form it goes back to the default view and not the search page.

      ReplyDelete
      Replies
      1. Hi Shaun, opening the properties in dialog is an interesting idea. You could definitely modify the link in my code to open a dialog. Refer to this article for relevant information for this option: http://blogs.msdn.com/b/sharepointdev/archive/2011/06/23/how-to-open-a-list-form-in-a-modal-dialog-box.aspx

        The referring page is a little more difficult and has been discussed in the following blog (under Step 3 continued: Occam's Razor): http://jesse.kimofkims.com/kb/420

        Delete
    5. Hi Robert, I'm running into an issue where the doc library name isn't getting included. Here's the url: http://Mywork/corp/IT//Forms/DispForm.aspx?id=12

      ReplyDelete
      Replies
      1. Try outputting the $itemUrl and $basicFour values in the xslt to troubleshoot the problem. One of them is likely not configured correctly or has a case sensitivity issue.

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

        Delete
      3. Chris may have found a solution for your issue. See below.

        Delete
    6. How can we configure this for image types .
      I have tried using $contentclass=STS_ListItem_PictureLibrary , however it doesn't work.
      Am I missing something here ?

      Regards,
      Kishore

      ReplyDelete
    7. Thanks a ton for taking the time to make this tutorial. This worked great for me. I had a similar issue as Vibol Hen above I believe, where the $library variable was outputting null essentially.

      It seemed necessary to make the basicFour variable all lower case as well to resolve this. I changed:

      <xsl:variable name="library" select="substring-before(concat(substring-after(translate($siteUrl, $uppercase, $smallcase), concat($basicFour, '/')), '/'), '/')" />
      to
      <xsl:variable name="library" select="substring-before(concat(substring-after(translate($siteUrl, $uppercase, $smallcase), concat(translate($basicFour, $uppercase, $smallcase), '/')), '/'), '/')" />

      And then the links were working correctly on sites that weren't all lower case. Thanks again!

      ReplyDelete
      Replies
      1. Thank you for the feedback. I updated the code with your changes.

        Delete
    8. This comment has been removed by the author.

      ReplyDelete