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 4006 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 2726 posts 8320 karma points MVP 4x 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 2726 posts 8320 karma points MVP 4x 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>

     

  • 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