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 :)

Please Sign in or register to post replies

Write your reply to:

Draft