Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Vanja Tesin 30 posts 55 karma points
    Oct 07, 2009 @ 12:18
    Vanja Tesin
    0

    Bug when matching displayFieldText from a list of preview fields

    Hi,

    We've stumbled on a rather curious bug in XSLTSearch version 2.8 on Umbraco 4. Let me explain the setup. We have the following parameters:

    searchFields="@nodeName,content,pageKeywords,pageDescription"
    previewFields="nodeName,content,pageKeywords,pageDescription"

    I know that this order is not according to the documentation, but this is a workaround for the bug at the moment.

    We have two pages, both having meta data, description and content filled in. First we try search term that is only located in content field. Result page looks fine - context is shown.

    If we now try search term that is only located in the meta data (pageKeywords) we have a search result that does not have it's context displayed (says unavailable).

    The trick is that template "displayFieldText" only tries to find first field that has any data and matches the parameter in the list without checking that this field is actually the field where match occured.

    In our case content is the first field that has any data but the match occured in pageKeywords. Later in the XSLTsearch the result of the "displayFieldText" template is used to created the context for the result page, but since the actual term occured in different field, it can't be found thus unavailable is shown.

    Here is the patched template that now checks for the context of the search in the preview field:

    <xsl:template name="displayFieldText">
        <xsl:param name="item"/>
        <xsl:param name="fieldList"/>
        <xsl:param name="previewChars"/>
        <xsl:param name="search"/>

        <xsl:variable name="fieldName">
          <xsl:value-of select="ps:getFirstElement($fieldList, ',')"/>
        </xsl:variable>
        <xsl:variable name="remainingFields">
          <xsl:value-of select="ps:removeFirstElement($fieldList, ',')"/>
        </xsl:variable>

        <xsl:variable name="fieldData" select="string($item/data[@alias=$fieldName])"/>
        <!-- contents of search result -->
        <xsl:variable name="strippedHTML" select="umbraco.library:StripHtml($fieldData)"/>

        <xsl:variable name="escapedData">
          <xsl:choose>
            <!-- display content of the search result, if available -->
            <xsl:when test="string($strippedHTML) != ''">
              <xsl:value-of select="$strippedHTML"/>
            </xsl:when>
          </xsl:choose>
        </xsl:variable>

        <xsl:variable name="context" select="ps:contextOfFind(string($escapedData), $search, 5, 5, $previewChars)"/>

        <xsl:choose>
          <!-- actually print out field, if it exists and has content that actually matches the search -->
          <xsl:when test="count($item/data[@alias=$fieldName]) = 1 and string($item/data[@alias=$fieldName]) != '' and string($context) != ''">
            <xsl:value-of select="string($item/data[@alias=$fieldName])"/>
          </xsl:when>

          <xsl:when test="$remainingFields != ''">
            <!-- if this element does not exist, go on to the next one -->
            <xsl:call-template name="displayFieldText">
              <xsl:with-param name="item" select="$item"/>
              <xsl:with-param name="fieldList" select="$remainingFields"/>
              <xsl:with-param name="previewChars" select="$previewChars"/>
              <xsl:with-param name="search" select="$search"/>
            </xsl:call-template>
          </xsl:when>
        </xsl:choose>
      </xsl:template>

     

  • Douglas Robar 3570 posts 4711 karma points MVP ∞ admin c-trib
    Oct 07, 2009 @ 12:23
    Douglas Robar
    0

    Nice modification to meet your needs! Thanks for sharing.

    cheers,
    doug.

  • Vanja Tesin 30 posts 55 karma points
    Oct 07, 2009 @ 12:29
    Vanja Tesin
    0

    You're welcome Douglas!

    Hopefully it will be of use to someone else as well :)

    Regards,

    Vanja

  • Robert 9 posts 29 karma points
    Oct 08, 2010 @ 10:24
    Robert
    0

    I've tried this and changed this to the new coding, but unfortunately I get "Error parsing XSLT file: \xslt\XSLTSearch.xslt " any thoughts?

     

    <xsl:template name="displayFieldText">
      <xsl:param name="item"/>
      <xsl:param name="fieldList"/>
      <xsl:param name="previewChars"/>
      <xsl:param name="search"/>
      
      
      <xsl:variable name="fieldName">
        <xsl:value-of select="ps:getFirstElement($fieldList, ',')"/>
        </xsl:variable>
        <xsl:variable name="remainingFields">
        <xsl:value-of select="ps:removeFirstElement($fieldList, ',')"/>
      </xsl:variable>

      <xsl:variable name="fieldData" select="string($item/* [name() = $fieldName and not(@isDoc)])"/>
      <!-- contents of search result -->
      <xsl:variable name="strippedHTML" select="umbraco.library:StripHtml($fieldData)"/>

      <xsl:variable name="escapedData">
        <xsl:choose>
          <!-- display content of the search result, if available -->
          <xsl:when test="string($strippedHTML) != ''">
            <xsl:value-of select="$strippedHTML"/>
          </xsl:when>
        </xsl:choose>
      </xsl:variable>

      <xsl:variable name="context" select="ps:contextOfFind(string($escapedData), $search, 5, 5, $previewChars)"/>
      <xsl:choose>
        <!-- actually print out field, if it exists and has content that actually matches the search -->
        <xsl:when test="count($item/* [name() = $fieldName and not(@isDoc)]) = 1 and string($item/* [name() = $fieldName and not(@isDoc)]) != '' and string($context) != ''">
          <xsl:value-of select="string($item/* [name() = $fieldName and not(@isDoc)])"/>
        </xsl:when>
      
        <xsl:when test="$remainingFields != ''">
          <!-- if this element does not exist, go on to the next one -->
          <xsl:call-template name="displayFieldText">
            <xsl:with-param name="item" select="$item"/>
            <xsl:with-param name="fieldList" select="$remainingFields"/>
            <xsl:with-param name="previewChars" select="$previewChars"/>
            <xsl:with-param name="search" select="$search"/>
          </xsl:call-template>
        </xsl:when>
      </xsl:choose>
    </xsl:template>

  • Robert 9 posts 29 karma points
    Oct 08, 2010 @ 11:07
    Robert
    0

    I fixed this using 2.8.1.

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Jan 12, 2011 @ 16:58
    Sebastiaan Janssen
    0

    I had to update this a little bit as well as the params were conflicting with some variable names, two updates: 

    <xsl:variable name="displayField">
        <xsl:call-template name="displayFieldText">
            <xsl:with-param name="item" select="."/>
            <xsl:with-param name="fieldList" select="$previewFields"/>
            <xsl:with-param name="previewCharsContext" select="$previewChars"/>
            <xsl:with-param name="searchContext" select="$search"/>
        </xsl:call-template>
    </xsl:variable>

    and:

      <xsl:template name="displayFieldText">
        <xsl:param name="item"/>
        <xsl:param name="fieldList"/>
        <xsl:param name="previewCharsContext"/>
        <xsl:param name="searchContext"/>
    
        <xsl:variable name="fieldName">
          <xsl:value-of select="ps:getFirstElement($fieldList, ',')"/>
        </xsl:variable>
        <xsl:variable name="remainingFields">
          <xsl:value-of select="ps:removeFirstElement($fieldList, ',')"/>
        </xsl:variable>
    
        <xsl:variable name="fieldData" select="string($item/data[@alias=$fieldName])"/>
        <!-- contents of search result -->
        <xsl:variable name="strippedHTML" select="umbraco.library:StripHtml($fieldData)"/>
    
        <xsl:variable name="escapedData">
          <xsl:choose>
            <!-- display content of the search result, if available -->
            <xsl:when test="string($strippedHTML) != ''">
              <xsl:value-of select="$strippedHTML"/>
            </xsl:when>
          </xsl:choose>
        </xsl:variable>
    
        <xsl:variable name="context" select="ps:contextOfFind(string($escapedData), $searchContext, 5, 5, $previewCharsContext)"/>
    
        <xsl:choose>
          <!--actually print out field, if it exists and has content that actually matches the search-->
          <xsl:when test="count($item/data[@alias=$fieldName]) = 1 and string($item/data[@alias=$fieldName]) != '' and string($context) != ''">
            <xsl:value-of select="string($item/data[@alias=$fieldName])"/>
          </xsl:when>
    
          <xsl:when test="$remainingFields != ''">
            <!--if this element does not exist, go on to the next one-->
            <xsl:call-template name="displayFieldText">
              <xsl:with-param name="item" select="$item"/>
              <xsl:with-param name="fieldList" select="$remainingFields"/>
              <xsl:with-param name="previewCharsContext" select="$previewCharsContext"/>
              <xsl:with-param name="searchContext" select="$searchContext"/>
            </xsl:call-template>
          </xsl:when>
        </xsl:choose>
      </xsl:template>
Please Sign in or register to post replies

Write your reply to:

Draft