Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

Template Questions /

How to insert code after every third item?


Go to End
Reply


16 Posts   6673 Views

Avatar
superautomatic

Community Member, 53 Posts

29 January 2009 at 5:12am

Edited: 02/03/2009 11:02pm

I have a page that lists items in a portfolio using

      <% control ChildrenOf(portfolio) %>
         (do things)
      <% end_control %>

Each item is floted left and renders as a three column layout like this http://spiro.se/portfolio/

My problem is that since the portfolio items are not of equal height, I need to insert a <hr > after every third item. How do I do that in silverstripe templates?

Avatar
UncleCheese

Forum Moderator, 4094 Posts

29 January 2009 at 6:00am

This is unfortunately one of the shortcomings of CSS. Believe it or not, the most common solution is to give the items a fixed height and be mindful of the amount of content that goes into the box. You can use the LimitWordCount template function to help you with that. I happen to think it looks a lot nicer, too.

But.. If you want to do handle every third item, here's a good hack.

function PortfolioItems()
{
$items = $this->ChildrenOf('portfolio');
$i = 0;
foreach($items as $item)
{
$i++
$item->Third = ($i % 3 == 0);
}
return $items;
}

That should work.. haven't tested it or anything.

Avatar
Hamish

Community Member, 712 Posts

29 January 2009 at 8:53am

Edited: 29/01/2009 8:56am

Bring on HTML5.

I had a discussion with someone about this on the irc channel a while back. $iteratorPos is accessible from the dataobject, so you can add this to any subclass of ViewableData:

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

Then, in your template:

<% if Mod3 %>
   <hr >
<% end_if %>

(note: $this->iteratorPos is the iterator position of the current object in the DataObjectSet it is contained within)

Avatar
UncleCheese

Forum Moderator, 4094 Posts

29 January 2009 at 10:37am

Yeah, I tried $this->Pos and it didn't work. That was what I was looking for. Pos() must be a function that returns the property iteratorPos.

Avatar
superautomatic

Community Member, 53 Posts

30 January 2009 at 1:19am

Edited: 30/01/2009 1:29am

Hamish > That looks interesting. But how do I use it inside a controller?
Like:

<% control ChildrenOf(portfolio) %>
(do things)
<% if Mod3 %>
<hr >
<% end_if %>
<% end_control %>

Avatar
UncleCheese

Forum Moderator, 4094 Posts

30 January 2009 at 6:27am

Edited: 30/01/2009 6:29am

There's really no way to do that without decorating the DataObjectSet. Try it my way. It's uglier, but it's easier than decorating. The bigfoot guy might have another idea, though.

edit: I just noticed Hamish's note about iteratorPos being a property of the object. Therefore, all you need to do is put that Mod3() function on your object.

Avatar
bennettpr

Community Member, 37 Posts

2 March 2009 at 11:22am

This doesn't work for me - if I place the Mod3 call inside the control, it never gets called.
Outside the control it's fine.

EG:

$newShelf (gets called fine)
                  
<% control Children %>
<% if newShelf %> (doesn't get called and always resolves to false)
<p>new shelf</p>
<% end_if %>
<p><a href="$Link" title="$Title">$Title</a></p>
<% end_control %>

Controller code:

function newShelf() {
// output pos so we can test if the method is being called
echo $this->iteratorPos;
return (($this->iteratorPos % 3) == 0);
}

Any advice appreciated

Avatar
Sam

Administrator, 685 Posts

2 March 2009 at 11:32am

Put the newShelf() method in the Page class rather than Page_Controller.

* Methods put on the Page class are available anywhere - ie, within <% control %> blocks and things.
* Methods on the Page_Controller class are available only at the top level of a template.

Go to Top