Copied to clipboard

Flag this post as spam?

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


  • Paul A 133 posts 368 karma points
    Oct 19, 2011 @ 18:10
    Paul A
    0

    How to get position() in 'sub' templates

    Hi,

    I have some code that that's calling various templates from within templates (to compare 2 comma separated lists) ... Once I'm at the bottom level though, i.e. I've found what I'm looking for, how do I limit the output to a certain number?

    I can't use position() because that's the position of the node in the original for-each. I basically only want to output a couple of these match.

    <xsl:template name="matchedNode">
    <xsl:param name="item" />
    <li>
    <xsl:if test="count(preceding-sibling::li) &lt; 3">

    <xsl:call-template name="outputMatch">
    <xsl:with-param name="someNode" select="$item" />
    </xsl:call-template>

    </xsl:if> </li>
    </xsl:template>
  • Paul A 133 posts 368 karma points
    Oct 19, 2011 @ 18:13
  • Rich Green 2246 posts 4008 karma points
    Oct 19, 2011 @ 18:28
    Rich Green
    0

    Hey Paul,

    You seemed to have linked back to the same (this) post?

    Regards

    Rich

  • Paul A 133 posts 368 karma points
    Oct 19, 2011 @ 21:31
    Paul A
    0

    Let's try that again...!

    http://our.umbraco.org/forum/developers/xslt/9684-Compare-2-comma-separated-strings?p=1

    I was just linking to this to show that the point I want to start the counting is buried 3 templates deep. 

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Oct 19, 2011 @ 23:38
    Chriztian Steinmeier
    0

    Hi Paul,

    Depending on your scenario (which I'm having a little trouble figuring out) you can try various options. The count(preceding::li) is a good one, but somehow you allude to that not working, or..?

    Passing a value on from template to template using parameters is another way you might be able to solve it.

    /Chriztian

     

  • Paul A 133 posts 368 karma points
    Oct 20, 2011 @ 11:40
    Paul A
    0

    Sorry, didn't explain well... (it's complicated!)... but basically at the very bottom level of my code I output the result. I want to add in some blurb that limits the number of outputted <li> to 3. I can't do this check higher up the code because I'm doing other bits (that's what the link to comparing comma lists was about)

    It looks to me like preceding-sibling is refering to nodes, where as I want it to refer to the outputted code. Is that not possible?

    count(preceding::li) returns 0 in this, as does preceding-sibling::li

    <xsl:template name="matchedNode">
        <xsl:param name="item" />
        <li><xsl:value-of select="count(preceding::li)" />.
            <xsl:if test="count(preceding-sibling::li) &lt; 2">   
                <xsl:call-template name="infoGuide">
                    <xsl:with-param name="infoGuideNode" select="$item" />
                </xsl:call-template>
            </xsl:if>
        </li>
    </xsl:template>

    Thanks for any help,

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Oct 21, 2011 @ 00:45
    Chriztian Steinmeier
    0

    Hi Paul,

    Yes, of course (!) - I totally didn't catch that.

    preceding-sibling:: (and all the other axes) works on the "input tree" not the "output tree", so of course you can't check for any <li> elements - I should have seen that right away :-)

    Normally, you'd do this by limiting the applied templates, but since you say you can't do the check above, you're probably in for some hair-pulling...

    You'll need to "do the math", so to speak, and figure out if the item you're going to output should be allowed to render itself;

    Can you figure it out by checking for preceding-siblings of the same type as the one you rendering? E.g.:

    <xsl:if test="count(preceding-sibling::*[name() = name($item)]) &lt; 2">

    - or is there more to it?

    /Chriztian

  • Paul A 133 posts 368 karma points
    Oct 21, 2011 @ 10:11
    Paul A
    0

    Thanks again for reply... That didn't work (outputing the count gave values 28, 24, 17, 5 etc) ... Basics below. We have lots of 'info guides' on the site, I want to pull through the latest 3 info guides based on certain categories (infoGuideFilter - multi checkbox)

    (it's only working if one category selected just now, I can worry about that after!)


    <xsl:param name="currentPage"/>

    <xsl:variable name="documentTypeAlias" select="string('DownloadRequestPage')"/>

    <xsl:template match="/">

    <xsl:variable name="values" select="umbraco.library:Split($currentPage/infoGuideFilter,',')" />
    <xsl:variable name="infoGuideRoot" select="umbraco.library:GetXmlNodeById(1234)" />


    <xsl:for-each select="$infoGuideRoot/* [name() = $documentTypeAlias and string(umbracoNaviHide) != '1']">
        <xsl:sort select="@createDate" order="descending" />

             
                <xsl:call-template name="displayTaggedItems">
                           <xsl:with-param name="tags" select="$values" />
                </xsl:call-template>
             
    </xsl:for-each>

    </xsl:template>


    <xsl:template name="displayTaggedItems">
      <xsl:param name="tags" select="tags" />

          <xsl:variable name="item" select="."/>
         
          <!-- Tags on current matched document -->
          <xsl:variable name="itemTags" select="Exslt.ExsltStrings:split($item/infoGuideCategories, ',')" />
         
          <!-- Run match against node sets from split() -->
          <xsl:variable name="isMatch">
            <xsl:call-template name="tokensMatch">
              <xsl:with-param name="set1" select="$tags"/>
              <xsl:with-param name="set2" select="$itemTags"/>
            </xsl:call-template>
          </xsl:variable>
         
          <!--
             tokensMatch template will return a string with an X for each tag matched -
             so an empty string is no match, any non-empty string a match
          -->
          <xsl:if test="string($isMatch) != ''">
            <!-- match found -->
        <xsl:call-template name="matchedNode">
            <xsl:with-param name="item" select="$item" />
        </xsl:call-template>

          </xsl:if>
     
     
    </xsl:template>

    <xsl:template name="matchedNode">
        <xsl:param name="item" />


        <li>--preceding-sibling = <xsl:value-of select="count(preceding-sibling::*[name() = name($item)])"/>.--
            <xsl:if test="count(preceding-sibling::*[name() = name($item)]) &lt; 3">   
                <xsl:call-template name="infoGuide">
                    <xsl:with-param name="infoGuideNode" select="$item" />
                </xsl:call-template>
            </xsl:if>
        </li>
    </xsl:template>

    <xsl:template name="tokensMatch">
      <xsl:param name="set1"/>
      <xsl:param name="set2"/>
     
      <xsl:for-each select="$set1">
        <xsl:variable name="v1" select="."/>
       
        <xsl:for-each select="$set2">
          <xsl:variable name="v2" select="."/>     
          <xsl:if test="string($v1) = string($v2)">X</xsl:if>
        </xsl:for-each>
      </xsl:for-each>
    </xsl:template>


    <xsl:template name="infoGuide">
        <xsl:param name="infoGuideNode" />
     
        <!-- outputs the info guide HTML -->

    </xsl:template>

    </xsl:stylesheet>

     

Please Sign in or register to post replies

Write your reply to:

Draft