Search

Hi,

Very new to Symphony, so any help much appreciated!

I have a Data Source containing many entries. When outputting on the page, I need to group the entries in 3s and wrap each group of 3 in 2 divs.

I have tried the following:

<xsl:for-each select="case-studies/entry">

    <xsl:if test="position() mod 3 = 1">                
        <div class="panel" title="1">
            <div class="wrapper">
    </xsl:if>  

    <div class="width-4">
        <img src="{$workspace}/img/cs_corp_social.jpg" alt="Corporate Social Responsibility" class="Framed"/>
        <h4 class="slide"><strong><xsl:value-of select="case-study-title" /></strong></h4>
        <p class="eleven"><xsl:copy-of select="substring(intro-text,1,459)"/>...<a href="{$root}/contact" class="link">contact us for more</a></p>            
    </div> 

    <xsl:if test="position() mod 3 = 1">                
        </div></div>
    </xsl:if>                                                           
</xsl:for-each>

This results in xslt processing errors, as the page thinks the divs opened inside the ifs, do not have closing tags.

What i need to do is loop through the entries in my data source, and at position 1,4, 7 etc...open the 2 containing divs, output 3 entries, then close the 2 divs. Repeat until end of entries.

Thanks in advance, Morgan

sorry, the code i pasted in has not appeared in the post. I've attached as a text file

Attachments

Don't forget that XSLT is actually XML. So your XSLT needs to read as valid, nested XML. That's where your code is tripping up, because you're trying to echo things out conditionally like PHP. In XSLT you could try this approach:

  • loop through the entries, testing when you're at the 1st, 4th, 7th etc
  • for each of these, have another loop to get the entries within that block (i.e. at position 1, you want to loop through 1, 2, 3; at position 4 you want to loop through 4, 5, 6).

How about this:

<xsl:for-each select="case-studies/entry">

    <!-- every fourth entry -->
    <xsl:if test="position() mod 4 = 1">

        <!-- write your div -->
        <div class="panel">
            <div class="wrapper">

                <!-- get this batch of 3 -->
                <xsl:for-each select="/data/case-studies/entry[position() &gt;= current()/position() and position() &lt;= (current()/position() + 2)]">
                    <div class="width-4">
                        ...
                    </div>              
                </xsl:for-each>

            </div>
        </div>

    </xsl:if>

<xsl:for-each>

I haven't tested, but should get you on the right track.

Nick,

Thanks so much for your help. I'd actually managed to get it working in the last hour, but have now replaced my code with your much more elegant solution!

Thanks again, Morgan

Cool, glad you got it working :)

Nick,

Sorry to be a nuisance! But I'm having a problem with the expression in your solution, the page shows the following error: could not compile select expression '/data/case-studies/entry[position() >= current()/position() and position() <= (current()/position() + 2)]'

I tried replacing both the '/' with 'div' which then allowed the page to render, but without outputting any of the content.

Any suggestions?

Got it working! Declared an xsl:variable called current-position and used the following:

<xsl:for-each select="/data/case-studies/entry[position() &gt;= $current-position and position() &lt;= $current-position + 2]">

Thanks again for pointing me in the right direction, I'll get the hang of XSLT eventually - its just so fundamentally different from the programming languages I'm used to!

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details