Copied to clipboard

Flag this post as spam?

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


  • Garrett Fisher 341 posts 496 karma points
    Jul 14, 2014 @ 22:59
    Garrett Fisher
    0

    Leveraging XSLT Search Package to Advance uComponents FilterNodes()

    Hi -- this is a question for you, @DouglasRobar, or indeed anyone who is able to offer some assistance.

    I am using the method ucomponents.xml:FilterNodes() for an Ajax resource library search screen on a site I'm working on.  I've got a bunch of dropdowns which reflect various properties of the handful of Doctypes involved and also a "contains" field for a free text search within the current returned nodeset, etc.  All is working fine.  However...

    Using the comparison between the user's text input and whatever text occurs in any nodenames or bodytext fields or metakeywords fields or whatever, I am only able to find EXACT matches of the string entered.  In other words, I am only searching for "all of" the keywords entered, and in that order.

    I noticed that the XSLT Search package, which I have always employed for my site-wide search in the header, is able to find "any of" the words entered by the user.  I then studied the code as best I could, but I'm afraid I was not able to determine how this is being done, at least not to the extent of getting me started in any direction.  I guess what I essentially need to do here is to "split" the words entered into the free text search field by a delimiter, in this case most likely a _space_, and to somehow work this into my FilterNodes() query, thus enabling the function to return documents that contain ANY OF the terms entered.

    Anyone out there understand my predicament and have ideas on how I might be able to make my search functionality more advanced int his way?

    I can offer up my current code but I'll wait for a reply first since this post is already probably too long to garner any attention!

    Thanks Forum,

    Garrett

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Jul 15, 2014 @ 00:03
    Chriztian Steinmeier
    0

    Hi Garrett,

    It doesn't sound too far-fetched to split the search term on spaces and then use contains() to look for ANY type matches.

    Problem is how to best filter the results - various options, depending on how your tree looks, which nodes and properties to search...

    Will gladly look at your code and provide tips for doing this

    /Chriztian

  • Garrett Fisher 341 posts 496 karma points
    Jul 15, 2014 @ 17:49
    Garrett Fisher
    0

    Chriztian!  Hey man.  Thanks for replying.  Here is bunch of existing (working) code -- I have bolded the areas I need to customize to allow for this inexact/flexible search:

    <xsl:template match="/">

    <xsl:variable name="contains" select="umbraco.library:RequestQueryString('contains')"/>
    <xsl:variable name="type"     select="umbraco.library:RequestQueryString('type')"/>
    <xsl:variable name="usecase"  select="umbraco.library:RequestQueryString('use-case')"/>
    <xsl:variable name="industry" select="umbraco.library:RequestQueryString('industry')"/>
    <xsl:variable name="product"  select="umbraco.library:RequestQueryString('product')"/>
    <xsl:variable name="platform"  select="umbraco.library:RequestQueryString('platform')"/>
    <xsl:variable name="startAt">
      <xsl:choose>
        <xsl:when test="normalize-space(umbraco.library:RequestQueryString('start'))">
          <xsl:value-of select="umbraco.library:RequestQueryString('start')"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>0</xsl:text>
        </xsl:otherwise>
    </xsl:choose>
      
    </xsl:variable>
      
    <!-- build query filter based on form values -->
    <xsl:variable name="filter">
      <xsl:if test="normalize-space($contains)">
        <xsl:variable name="containsString">
          <xsl:text>"</xsl:text>
          <xsl:value-of select="$contains"/>
          <xsl:text>"</xsl:text>
        </xsl:variable>
        <xsl:value-of select="
            concat('[contains(@nodeName, ', $containsString, ')
            or contains(resourceDescription, ', $containsString, ')
            or contains(resourceDescriptionShort, ', $containsString, ')
            or contains(mediaType, ', $containsString, ')
            or contains(metaKeywords, ', $containsString, ')
            ]')" />
      </xsl:if>
      <xsl:if test="normalize-space($type)">
        <xsl:variable name="mediaTypeString">
          <xsl:text>"</xsl:text>
          <xsl:value-of select="umbraco.library:GetPreValueAsString($type)"/>
          <xsl:text>"</xsl:text>
        </xsl:variable>
        <xsl:value-of select="concat('[mediaType = ', $mediaTypeString, ']')" />
      </xsl:if>
      <xsl:if test="normalize-space($usecase)">
        <xsl:value-of select="concat('[resourceUseCases//nodeId = ', $usecase, ']')" />         
      </xsl:if>
      <xsl:if test="normalize-space($industry)">
        <xsl:value-of select="concat('[resourceIndustries//nodeId = ', $industry, ']')" />              
      </xsl:if>
      <xsl:if test="normalize-space($product)">
        <xsl:value-of select="concat('[resourceProducts//nodeId = ', $product, ']')" />         
      </xsl:if>
      <xsl:if test="normalize-space($platform)">
        <xsl:variable name="platformString">
          <xsl:text>"</xsl:text>
          <xsl:value-of select="umbraco.library:GetPreValueAsString($platform)"/>
          <xsl:text>"</xsl:text>
        </xsl:variable>
        <xsl:value-of select="concat('[resourcePlatform = ', $platformString, ']')" />
      </xsl:if>
      <xsl:if test="not(normalize-space(concat($contains, $type, $usecase, $industry, $product, $platform)))">
        <xsl:text>[true()]</xsl:text>
      </xsl:if>
    </xsl:variable>

    <!-- run filter -->
    <xsl:variable name="filteredResources">
      <xsl:choose>
        <xsl:when test="normalize-space(concat($contains, $type, $usecase, $industry, $product, $platform))">
          <root>
            <xsl:copy-of select="ucomponents.xml:FilterNodes($currentPage, concat('
              ancestor-or-self::Home[@isDoc]//Resources[1][@isDoc]/ResourceType
              [@isDoc][not(umbracoNaviHide=1)]//*
              [@isDoc][not(umbracoNaviHide=1)]
              [(name()=&quot;LeadProtectedFile&quot; and normalize-space(resourceFile))
              or
              (name()=&quot;LeadProtectedVideo&quot; and normalize-space(embedCode))]',
              $filter))"/>
          </root>
        </xsl:when>
        <xsl:otherwise>
          <root>
            <xsl:copy-of select="$currentPage/ancestor-or-self::Home[@isDoc]//Resources[1]/ResourceType
              [@isDoc][not(umbracoNaviHide=1)]//*
              [@isDoc][not(umbracoNaviHide=1)]
              [(name()=&quot;LeadProtectedFile&quot; and normalize-space(resourceFile))
              or
              (name()=&quot;LeadProtectedVideo&quot; and normalize-space(embedCode))]"/>
          </root>
        </xsl:otherwise>
      </xsl:choose>  
    </xsl:variable>
        
      <!-- show results -->
      <xsl:choose>
        
        <!-- no filter; show featured items and latest 4 of each media type -->
        <xsl:when test="$filter = '[true()]'">
          
          <!-- switch to default view macro -->
          <xsl:value-of select="umbraco.library:RenderMacroContent('&lt;?UMBRACO_MACRO macroAlias=&quot;ResourceLibraryDefaultView&quot; /&gt;', $currentPage/@id)" disable-output-escaping="yes" />
          
        </xsl:when>
        <xsl:otherwise>
          
          <!-- filter has values; show search results -->
          
        </xsl:otherwise>
      </xsl:choose>
      
    </xsl:template>

    Just not sure how to place any additional functions into this since I alerady have a concat() AND a contains() going on -- I had actually been trying to force lowercase on this comparison at an earlier stage of development and was unable to figure that out either.  What I need is to compare the essentially tokenized ignore-case querystring value, with each of the comparison doctype properties indicated in the code, but so far it seems to have been beyond my skill level!

    Thanks again in advance, @Chriztian.

    Sincerely,

    Garrett

  • Garrett Fisher 341 posts 496 karma points
    Jul 17, 2014 @ 18:52
    Garrett Fisher
    0

    Hi Chriztian -- hope my code didn't scare you away ;) Have you had a chance to look at my problem?

    Thanks again,

    Garrett

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Jul 28, 2014 @ 16:53
    Chriztian Steinmeier
    0

    Hi Garrett,

    Not scared - overwhelmed maybe, but most of all on vacation :-)

    Will have a look soon!

    /Chriztian

  • Garrett Fisher 341 posts 496 karma points
    Jul 28, 2014 @ 22:06
    Garrett Fisher
    0

    Hi Chriztian -- I totally figured that out based on your usual response time :) ENJOY your time off and I'll look forward to hearnig from you when you get a chance!

    //Garrett

  • Garrett Fisher 341 posts 496 karma points
    Aug 18, 2014 @ 21:23
    Garrett Fisher
    0

    Hi Chiztian - wondering if you have had a chance to take a look at this yet?  I'm still stuck on it.

    Thanks again,

    Garrett

  • Garrett Fisher 341 posts 496 karma points
    Nov 14, 2014 @ 20:05
    Garrett Fisher
    0

    Bumping this post again - still need help on this if anyone can hear me!

    //Garrett

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Nov 17, 2014 @ 21:38
    Chriztian Steinmeier
    0

    Hi Garrett,

    I really want to help you with this, but honestly, I'd have a C# developer write an extension for this after adding the third search parameter... XSLT is not good at complex string manipulation (which is effectively what you're doing here - and that's already one step removed from the actual problem (dynamic XPath)).

    Still, it's possible to do it and I'd like to help you out - but I'll probably need to take it all apart and reassemble it - feel free to email me at (my firstname) @ (my lastname) .dk with maybe some links and the complete XSLT?

    We can post the final results here when finished to close the thread properly.

    /Chriztian

Please Sign in or register to post replies

Write your reply to:

Draft