Copied to clipboard

Flag this post as spam?

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


  • Niels 63 posts 119 karma points
    Oct 27, 2011 @ 14:35
    Niels
    0

    Multiple-Node Tree Picker (uComponents) challenge

    I want to use the MNTP to catagorize nodes/products, to accomplish this I want select a few category-nodes on every node/product. 

    On the categorie-pages I want to show the nodes which are relevant/selected for that page. I try to do the following thing in the xslt (with paging):

    <?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:umbraco.library="urn:umbraco.library"
      exclude-result-prefixes="msxml umbraco.library">
      <xsl:output method="xml" omit-xml-declaration="yes" />
      <xsl:include href="_pagination.xslt"/>
      <xsl:param name="currentPage"/>
      <xsl:variable name="page" select="umbraco.library:RequestQueryString('page')" />
      <xsl:template match="/">
        <xsl:variable name="matchedNodes" select="$currentPage/descendant::*[@isDoc and selectCategories = 'parentID']" />
        <xsl:variable name="nodeCount" select="count($matchedNodes)" />
        <xsl:if test="$nodeCount &gt; 0">
          <xsl:variable name="page">
            <xsl:choose>
              <!-- first page -->
              <xsl:when test="number(umbraco.library:RequestQueryString('page')) &lt;= 1 or string(umbraco.library:RequestQueryString('page')) = '' or string(number(umbraco.library:RequestQueryString('page'))) = 'NaN'">
                <xsl:value-of select="number('1')" />
              </xsl:when>
              <!-- last page -->
              <xsl:when test="number(umbraco.library:RequestQueryString('page')) &gt; $nodeCount div $resultsPerPage">
                <xsl:value-of select="ceiling($nodeCount div $resultsPerPage)" />
              </xsl:when>
              <!-- the value specified in the url -->
              <xsl:otherwise>
                <xsl:value-of select="number(umbraco.library:RequestQueryString('page'))"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:variable>
          <xsl:variable name="startMatch" select="($page - 1) * $resultsPerPage + 1" />
          <xsl:variable name="endMatch">
            <xsl:choose>
              <!-- all the rest (on the last page) -->
              <xsl:when test="($page * $resultsPerPage) &gt; $nodeCount">
                <xsl:value-of select="$nodeCount" />
              </xsl:when>
              <!-- only the appropriate number for this page -->
              <xsl:otherwise>
                <xsl:value-of select="$page * $resultsPerPage" />
              </xsl:otherwise>
            </xsl:choose>
          </xsl:variable>
          <xsl:if test="$matchedNodes">
            <xsl:apply-templates select="$matchedNodes">
              <xsl:sort select="@createDate" order="descending" data-type="text" />
              <xsl:with-param name="startMatch" select="$startMatch" />
              <xsl:with-param name="endMatch" select="$endMatch" />
            </xsl:apply-templates>
          </xsl:if>
          <xsl:if test="$nodeCount &gt; $resultsPerPage">
            <xsl:call-template name="pagination">
              <xsl:with-param name="page" select="$page" />
              <xsl:with-param name="matchedNodes" select="$matchedNodes" />
            </xsl:call-template>
          </xsl:if>
          </xsl:if>
      </xsl:template>
      <xsl:template match="*[@isDoc]">
        <xsl:param name="startMatch" />
        <xsl:param name="endMatch" />
        
        <xsl:if test="position() &gt;= $startMatch and position() &lt;= $endMatch">
            <div class="product">
                <xsl:variable name="afbeelding1" select="number(afbeelding1)" />
                <xsl:if test="$afbeelding1 > 0">
                  <xsl:variable name="mediaNode" select="umbraco.library:GetMedia($afbeelding1, 0)" />
                  <xsl:if test="$mediaNode/umbracoFile">
                    <a class="layoverlink" title="{@nodeName}" href="{$mediaNode/umbracoFile}" rel="shadowbox[{$currentPage/@nodeName}]"><img src="/images/layoverlink.png" alt="{@nodeName}" /></a>
                  <img src="/ImageGen.ashx?image=/{$mediaNode/umbracoFile}&amp;height=125&amp;width=220" alt="{@nodeName}" />
                  </xsl:if>
                </xsl:if>
                <h2><a title="Bekijk product" href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="@nodeName" disable-output-escaping="yes"/></a></h2>
                <table>
                  <tr>
                  <td>Prijs:</td>
                  <td><b>&#x20AC; <xsl:value-of select="(prijs)" disable-output-escaping="yes" />,-</b></td>   
                  </tr>
                  <tr>
                  <td>Afmetingen:</td>
                  <td><b><xsl:value-of select="(afmetingen)" disable-output-escaping="yes" /></b></td>  
                  </tr>
                  <tr>
                  <td>Bekleding:</td>
                  <td><b><xsl:value-of select="(bekleding)" disable-output-escaping="yes" /></b></td>  
                  </tr>
                </table>
                  <span class="green"><a title="Bekijk product" href="{umbraco.library:NiceUrl(@id)}">Bekijk product</a> </span>
                </div>
          </xsl:if>
      </xsl:template>
    </xsl:stylesheet>

    Please help me on this one.

  • Niels 63 posts 119 karma points
    Oct 28, 2011 @ 10:53
    Niels
    0

    No one?

  • Dan Okkels Brendstrup 101 posts 197 karma points
    Oct 28, 2011 @ 10:55
    Dan Okkels Brendstrup
    2

    I've done something similar using keys, which are perfect for this.

    If you have a Product doctype with a categories property, which is an MNTP that allows the user to select one or more Category nodes, then you can do something like the following:

    <xsl:key name="products-by-category" match="Product" use="categories//nodeId"/>
    <xsl:template match="Category">
       <xsl:apply-templates select="key('products-by-category', @id)"/>
    </xsl:template>

    You're essentially creating an index of Product nodes that kan be queried by the @id of their associated categories, and when you render your Category page, you simply apply-templates to the products that are associated with that category.

  • Niels 63 posts 119 karma points
    Oct 28, 2011 @ 16:11
    Niels
    0

    I've tried your solution, but it doesn't worked for me. It returns no value.

  • Lee Kelleher 4026 posts 15837 karma points MVP 13x admin c-trib
    Oct 28, 2011 @ 17:23
    Lee Kelleher
    1

    Hi Niels,

    Taking away all the pagination noise from your XSLT (I should know, I wrote it - LOL!), you essentially need to select the correct nodes for the "matchedNodes" variable:

    <xsl:variable name="matchedNodes" select=" ... XPath for nodes with selected category ... " />

    So, couple of questions... are you using XML as the data-format for your MNTP? For this, you should do - makes it much easier!

    Now is this XSLT being ran on the category page itself? Meaning that the $currentPage/@id could be a value in the "selectedCategory"?

    You could try this XPath:

    <xsl:variable name="matchedNodes" select="$currentPage/descendant::*[@isDoc and selectCategories/MultiNodePicker/nodeId = $currentPage/@id]" />

    Most likely need to play around with the XPath until it's right.

    Cheers, Lee.

  • Dan Okkels Brendstrup 101 posts 197 karma points
    Oct 28, 2011 @ 17:43
    Dan Okkels Brendstrup
    2

    Ah, good point from Lee on ensuring that the MNTP saves data as XML -- that is also required for my key example. And I didn't think to add it, but my example also requires a template to actually output the Product data, e.g.:

    <xsl:template match="Category">
      <ul>
       <xsl:apply-templates select="key('products-by-category', @id)"/>
      </ul>
    </xsl:template>

    <xsl:template match="Product">
       <li><xsl:value-of select="@nodeName"/></li>
    </xsl:template>
  • Lee Kelleher 4026 posts 15837 karma points MVP 13x admin c-trib
    Oct 28, 2011 @ 18:15
    Lee Kelleher
    1

    Hi Dan,

    I usually use keys too - love 'em! So a good fit for Niels solution would be:

    <xsl:key name="products-by-category" match="*[@isDoc]" use="selectCategories/MultiNodePicker/nodeId"/>
    <xsl:variable name="matchedNodes" select="key('products-bt-category', $currentPage/@id)" />
    

    Cheers, Lee.

  • Niels 63 posts 119 karma points
    Oct 31, 2011 @ 15:11
    Niels
    0

    Hi Dan and Lee, Thanks for your reactions.

    The solution that Lee mentioned work fine for child pages of a category, but in this case the products are on the same level as the categories. Now I changed the xpath to (so only the nodes with the ProductDetail will be displayed):

    <xsl:variable name="matchedNodes" select="$currentPage/descendant::ProductDetail[@isDoc and selectCategories/MultiNodePicker/nodeId = $currentPage/@id and @level = 4]" />

    But this returns nothing, i'm now playing around with this xpath. I hope to get back with the solution soon. ( help is appreciated ;-) )

    Thanks Dan for mentioning the technique with 'keys', I will definitely be using that in the near future.

  • Dan Okkels Brendstrup 101 posts 197 karma points
    Oct 31, 2011 @ 21:33
    Dan Okkels Brendstrup
    1

    If the categories and the product detail pages are on the same level, then the problem is the descendent:: axis, since you're looking for siblings rather than descendants.

    Also, since ProductDetail is a doctype, then the [@isDoc] test is superfluous (the [@level] test might be as well, but that depends on your XML). So I'd think that this should work:

    <xsl:variablename="matchedNodes"select="$currentPage/../ProductDetail[selectCategories/MultiNodePicker/nodeId = $currentPage/@id and @level = 4]"/>
  • Niels 63 posts 119 karma points
    Nov 02, 2011 @ 09:21
    Niels
    0

    Sorry for not getting back to you sooner, but thanks a lot! You've made my day guys! 

    Thanks for the explaining, it helps me further to understand xslt and Umbraco. 

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies