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: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>
<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>
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:
Nice modification to meet your needs! Thanks for sharing.
cheers,
doug.
You're welcome Douglas!
Hopefully it will be of use to someone else as well :)
Regards,
Vanja
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>
I fixed this using 2.8.1.
I had to update this a little bit as well as the params were conflicting with some variable names, two updates:
and:
is working on a reply...