Copied to clipboard

Flag this post as spam?

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


  • Kevin Farrow 46 posts 67 karma points
    Sep 20, 2010 @ 16:21
    Kevin Farrow
    0

    Adding <div> around every 3rd item returned from GetXmlAll()

    Wonder if anyone can help me. I need to output some html (that is already in an existing system) similar to the following:

    <div id="row">

      <div class="col">
      </div>

      <div class="col">
       </div>

      <div class="col last">
       </div>

    </div>

    I am using GetXmlAll() and filtering the nodeType i.e.

    <xsl:for-each select="umbraco.library:GetXmlAll()//* [@nodeType='1074' and umbracoNaviHide != '1']">

    and am using the following code to set the "col last" class on the 3rd item i.e.

    <xsl:if test="position() mod 3 = 0">
    <xsl:attribute name="class">
      <xsl:text>col last</xsl:text>
    </xsl:attribute>
    </xsl:if>

    The problem is that I only need to output the <div id="row"> ... </div> around every 3rd item but if I use the following code I get errors telling me there is no closing element i.e. the "</div>"

    <xsl:when test="position() mod 4 = 0 or position() = 1">
      <div id="row">
    </xsl:when>
    </xsl:choose>

    Any help would be much appreciated.

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Sep 20, 2010 @ 22:06
    Chriztian Steinmeier
    6

    Hi Kevin,

    The way you do this in XSLT demands a somewhat radical shift in thinking, so I'll post the code with comments and hopefully you'll be able to grasp the idea and tweak it to your specific needs:

    <?xml version="1.0" encoding="utf-8" ?>
    <xsl:stylesheet
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:make="urn:schemas-microsoft-com:xslt"
        xmlns:umbraco.library="urn:umbraco.library"
        exclude-result-prefixes="umbraco.library make"
    >
    
        <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
    
        <xsl:param name="currentPage" />
        <xsl:variable name="root" select="$currentPage/ancestor-or-self::root" />
    
        <!-- Grab the data to output -->
        <xsl:variable name="nodes">
            <xsl:copy-of select="$root//*[@nodeType = 1074][not(umbracoNaviHide = 1)]" />
        </xsl:variable>
        <!-- Enable XPath selection in nodes -->
        <xsl:variable name="data" select="make:node-set($nodes)" />
    
        <xsl:template match="/">
            <!-- Apply templates to every third document, starting with the first  -->
            <xsl:apply-templates select="$data/*[position() mod 3 = 1]" mode="row" />
        </xsl:template>
    
        <!-- Template to start a row -->
        <xsl:template match="*[@nodeType = 1074]" mode="row">
            <div class="row">
                <!-- Now render this document and the following 2 -->
                <xsl:apply-templates select=". | following-sibling::*[@nodeType = 1074][position() &lt; 3]" mode="col" />
            </div>
        </xsl:template>
    
        <!-- Template for a column -->
        <xsl:template match="*[@nodeType = 1074]" mode="col">
            <div class="col">
                <!-- Redefine class for every third item -->
                <xsl:if test="position() mod 3 = 0">
                    <xsl:attribute name="class">col last</xsl:attribute>
                </xsl:if>
                <xsl:value-of select="@nodeName" />
            </div>
        </xsl:template>
    
    </xsl:stylesheet>
    

    /Chriztian

  • Peter Duncanson 430 posts 1360 karma points c-trib
    Sep 20, 2010 @ 22:20
    Peter Duncanson
    0

    Chriztian, love how you rename the msxml namespace as "make" reads better ;)

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Sep 20, 2010 @ 22:33
    Chriztian Steinmeier
    0

    @Pete:

    Yep - methinks too. Also, it's actually because (as you may already know) I do all my XSLT coding on my MacBook Pro, so that prefix is actually mapped to "http://exslt.org/common" when I code. I just swap the MS-namespace in before pasting here :-)

    /Chriztian 

  • Kevin Farrow 46 posts 67 karma points
    Sep 20, 2010 @ 22:54
    Kevin Farrow
    0

    Thanks Chriztian. I was resigned to trying to do it in a user control as I don't think I could have worked it out myself.

    I don't know about anyone else, but I find XSLT makes as much sense as spaghetti with it's slashes and colons, and now 4.5 uses a different way doing everything just as I was getting used to it (in my own limited way ;-))

    Thanks again,
    Kevin

     

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Sep 20, 2010 @ 23:00
    Chriztian Steinmeier
    0

    Hang in there Kevin; the 4.5 XML format makes it so much easier to "read" what's going on, trust me :-)

    But you'll always have all the smart heads in the entire Umbraco Community to ask when stuff goes up in smoke... 

    /Chriztian

  • Tom Fulton 2030 posts 4998 karma points c-trib
    Sep 20, 2010 @ 23:07
    Tom Fulton
    1

    Since I never really understood the method Chriztian posted, I typically follow your attempted approach, but get around the closing tag error by encoding it so it's not detected as a tag by the parser.  Probably not the right way of doing things but it's more of a quick fix/hack:

    <xsl:when test="position() mod 4 = 0 or position() = 1">
      <xsl:text disable-output-escaping="yes">&lt;div id="row"&gt;</xsl:text>
    </xsl:when>

    ...

    <xsl:when test="position() mod 4 = 0 or position() = 1">
      <xsl:text disable-output-escaping="yes">&lt;/div&gt;</xsl:text>
    </xsl:when>

    Going to try Chriztian's method next time - his comments make it much easier to follow :)

  • Scott Murphy 2 posts 23 karma points
    Jan 31, 2012 @ 21:04
    Scott Murphy
    1

    Chriztian ,

    Thanks so much for that code snippet!  I was able to tweak it a little bit to add a div around every fourth item.

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Jan 31, 2012 @ 21:12
    Chriztian Steinmeier
    1

    Way to go Scott! On the very day they release the "XSLT-Obliterator" (V5, that is) you say, "Nay - I'll use this awesome snippet here and be done with it."

    Thanks :-)

    /Chriztian

  • LordToro 9 posts 29 karma points
    Apr 26, 2012 @ 10:00
    LordToro
    0

    Thanks  Chriztian :)

  • 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