Copied to clipboard

Flag this post as spam?

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


  • Fergus Davidson 309 posts 588 karma points
    Mar 24, 2010 @ 15:12
    Fergus Davidson
    0

    XSLT Search Term highlighting

    hi

    i know that XSLTSearch does a lovely job of highlighting the terms on the results page, but every now and again, when a page has a lot of text, it is nice to have this feature passed from the results page to the page which is linked from the result.

    My question[s]:

    would the best way to achieve this be to pass the term in the link to the page and then wash the pages content through a macro in a similar way to that which XSLTSearch does on the results page?

    Is there a better way?

    many thanks

     

    fergus

  • Douglas Robar 3570 posts 4711 karma points MVP ∞ admin c-trib
    Mar 24, 2010 @ 15:42
    Douglas Robar
    0

    Hi, Fergus,

    I would handle it basically the way you describe.

    First, I'd modify XSLTsearch.xslt to append the search term(s) to the href of all links returned in the results of XSLTsearch.

    Then I'd make a macro to display the 'bodyText' and any other fields on your template rather than using <umbraco:Item>. That macro would grab the search term(s) from the querystring and put some markup around all occurances of those terms. You could certainly take a bunch of the code from XSLTsearch.xslt to handle this. Or you could handle it as a .net macro that would probably be cleaner since XSLT is pretty terrible at string manipulation.

    cheers,
    doug.

  • Fergus Davidson 309 posts 588 karma points
    Mar 24, 2010 @ 17:26
    Fergus Davidson
    0

    thanks doug.

    i think for the short term i will go the xslt route, but i may go the .net route if i have any trouble with the strings.

     

    thanks again!

     

  • Fergus Davidson 309 posts 588 karma points
    Mar 24, 2010 @ 23:18
    Fergus Davidson
    0

    just in case this is useful for anyone else, or if anyone wants to tell me that this is an absurd way to go about it, i ended up using the following:

    xslt search results pass the term in the url 

    page then calls macro with the following xslt. c# function carries out a case-insensitive replace for the search term.

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE xsl:stylesheet [
        <!ENTITY nbsp "&#x00A0;">
    ]>
    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxml="urn:schemas-microsoft-com:xslt"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt"
        xmlns:umbraco.library="urn:umbraco.library"
        xmlns:fhd="urn:bl_ndp_lot:xslt"
        exclude-result-prefixes="msxml umbraco.library">
    
    <xsl:output method="xml" omit-xml-declaration="yes" />
    <xsl:param name="currentPage"/>
    <xsl:template match="/">
        <xsl:variable name="source" select="$currentPage/data [@alias = 'bodyText']"/>
        <xsl:choose>
            <xsl:when test="string(umbraco.library:RequestQueryString('term')) != ''">
                <xsl:value-of select="fhd:ReplaceEx($source,string(umbraco.library:RequestQueryString('term')),'HOORAY')" disable-output-escaping="yes" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$source" />::FINISHED::
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    <msxsl:script language="C#" implements-prefix="fhd">
    <![CDATA[
        public static string ReplaceEx(string original, string pattern, string replacement)
        {
                int count, position0, position1;
                count = position0 = position1 = 0;
                string upperString = original.ToUpper();
            string upperPattern = pattern.ToUpper();
                int inc = (original.Length/pattern.Length) * (replacement.Length-pattern.Length);
                char [] chars = new char[original.Length + Math.Max(0, inc)];
                while( (position1 = upperString.IndexOf(upperPattern, position0)) != -1 )
                {
                    for ( int i=position0 ; i < position1 ; ++i )
                        chars[count++] = original[i];
                for ( int i=0 ; i < replacement.Length ; ++i )
                    chars[count++] = replacement[i];
                    position0 = position1+pattern.Length;
                }
                if ( position0 == 0 ) return original;
                for ( int i=position0 ; i < original.Length ; ++i )
                    chars[count++] = original[i];
                return new string(chars, 0, count);
        }
    ]]>
    </msxsl:script>
    </xsl:stylesheet>

    i still need to sort out the multi word search terms, but this handles the single words just fine.

    any thoughts anyone?

Please Sign in or register to post replies

Write your reply to:

Draft