Home

Manipulating every Nth item in a <% control %> loop

Often you will want to manipulate every nth item inside a <% control %> loop. For example say you had a gallery and you wanted every 3rd image to start on a new line, you need to be able to test each item from the template to see if it is divisible by 3 and should therefore have the clear CSS class added to it.

Using iteratorPos % we can very easily achieve this. First we need to add the test function to the object we will be iterating through, so for example if you are iterating through a number of ImageItem DataObjects, we would add this function to our ImageItem class:

The % operator calculates the modulous or Remainder after dividing by the number that follows it (in this case 3). If there is a remainder then we know that the item is not divisible by 3 and so should not be cleared, but if the modulous is equal to 0 then we know it is divisible by 3 and should therefore clear a new line. 

We can now use <% if IsThird %> to clear the third image in our control loop like so:

About the Author

Name: Aram Balakjian

Website: http://www.aabweb.co.uk

Aram is a web designer/developer running London based agency aab web. He has a strong passion for developing attractive, usable sites around the SilverStripe CMS.

Comments (10)

  • You can also include some error checking;

    public function isiteratorPos($i=2){
    return $this->iteratorPos>0 && ($this->iteratorPos % $i) == 0;
    }

    Posted by Matt Clegg, 06/05/2010 1:53pm (3 months ago)

  • How about:

    function Position(){
    switch($this->iteratorPos % 3) {
    case 0: return 'first'; break;
    case 1: return 'second'; break;
    case 2: return 'third'; break;
    }
    }

    then you can just go eg: <li class="$Position">

    Posted by Chris, 23/04/2010 1:54am (3 months ago)

  • After some playing with it I noticed (as I have done before) that in order to get it to work on page objects you have to add it to the model and not to the controler ...

    Posted by yurigoul, 28/02/2010 7:31am (5 months ago)

  • Is there a way to get this working on a Children control that returns more than one DataObject Type. Adding the function to each

    Posted by Richard Rudy, 13/01/2010 8:21am (7 months ago)

  • Will this work within any class?

    Posted by Alan Tucker, 18/11/2009 5:08am (8 months ago)

  • This code not work
    becose iteratorPoss = 0
    where I mast add
    $this->iteratorPos++

    Posted by vitaliy, 10/11/2009 6:23am (9 months ago)

  • Hi Markus

    That sounds like a great idea, if you want to write a snippet that would be great, or you can just send me your code and i will add it to this snippet :)

    Thanks

    Aram

    Posted by aram, 18/07/2009 10:38am (1 year ago)

  • Great post about a function that really should be part of the core.

    I've found myself writing a couple of utility functions to extend the template language but I didn't like having to put them in my Page class or inte class of the dataobject in question.

    I solved this by decorating so I can keep my utility functions separate from my page/dataobject files.

    I would be most willing to write a snippet about this if you think going the decorator route instead of putting them directly in the classes is a worthwile one.

    Posted by Marcus, 17/07/2009 5:45pm (1 year ago)

  • Thanks guys! They both worked perfectly so I have changed the post accordingly :)

    Posted by Aram , 17/07/2009 7:03am (1 year ago)

  • Hi all, I use this one (with modulous) and it works pretty well....passing in the number of iterations makes it a little more flexibe:

    public function SplitList($val=3) {
    return ($this->iteratorPos ) % $val == 0;
    }

    Posted by nick jacobs, 16/07/2009 3:06pm (1 year ago)

RSS feed for comments on this page RSS feed for all comments

Post your comment