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 4020 posts 15802 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 4020 posts 15802 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. 

Please Sign in or register to post replies

Write your reply to:

Draft