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.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Data Model Questions /

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Controlling pages in groups of certain size


Go to End


10 Posts   5026 Views

Avatar
Boogiez

Community Member, 17 Posts

5 February 2009 at 9:27pm

My scenario is that I have a page where I would like to control its children in groups of, say, 6, until it runs out of children (the last group would have the remainder).

So for example, if i have 14 children of my page i'd like to be able to product something that looks like this:

<div id="group1">
     <img src="image1.jpg">
     <img src="image2.jpg">
     <img src="image3.jpg">
     <img src="image4.jpg">
     <img src="image5.jpg">
     <img src="image6.jpg">
</div>
<div id="group2">
     <img src="image7.jpg">
     <img src="image8.jpg">
     <img src="image9.jpg">
     <img src="image10.jpg">
     <img src="image11.jpg">
     <img src="image12.jpg">
</div>
<div id="group3">
     <img src="image13.jpg">
     <img src="image14.jpg">
</div>

This would be supposing that each child had an attached image that happened to have a filename numbered according to its position, but that's unimportant because I'd just get attributes of each child using controls like $Link, $Title, etc. The important part is that the children are grouped by sixes.

The example HTML output above might be produced by something like:

<% control ChildrenBySixes %>
     <img src="$Link">
<% end_control %>

I've been thinking about this for some time and I Just can't seem to figure out anything that would actually work. I would assume that everything would need to be handled by the controller, but as far as I'm aware the controller doesn't let you spit out any HTML, which needs to appear periodically (the "</div><div id="group$nextGroupNum>" or similar, and of course you can't iterate in a template, which I need to do in order to cover all the children.

My second problem is that I can't quite seem to figure out how to construct a request for a DataObject of the children of the parent page, which I assume would probably be part of the solution.

Thanks for any help you might be able to offer!
- Mark

Avatar
BLU42 Media

Community Member, 71 Posts

6 February 2009 at 6:49am

Hi Mark-

This is just one way to get this done...

For the grouping you'll need to create a function in the object that you want to group (in this case, the child pages you want to gather). I'm assuming that you'll want a GroupNum function in here too :)

function Grouping() {
	if ($this->iteratorPos % 6 == 0) {
		return true;
	}
}

function GroupNum() {
	return floor($this->iteratorPos / 6) + 1;
}

In your template, you can set up some if blocks to check for the value. You can grab your children by using ChildrenOf('your-page-url')

<% control ChildrenOf('your-page-url') %>
<% if Grouping %>
<div id="group{$GroupNum}">
<% end_if %>
<img /> (fill in your details here)
<% if Grouping || Last %>
</div>
<% end_if %>
<% end_control %>

Let us know how it works out for you!

-John

Avatar
Boogiez

Community Member, 17 Posts

6 February 2009 at 8:06am

Thanks for your quick response! This is exactly what I want to do :D

Unfortunately, it is not working (yet).

Here's my the template code in the parent page (that is going to have the blocks of children in it):

		<% control Children %> 
			<% if Grouping %> 
				<div id="group{$GroupNum}"> 
			<% end_if %> 
				<p>Child: $Title</p>
			<% if Grouping || Last %> 
				</div> 
			<% end_if %> 
		<% end_control %>

I chose to replace ChildrenOf(page-url) with Children since I always will want the children listed to be the children of each specific ProductGallery (my parent page).

I added to the Controller your php, exactly:

	function Grouping() { 
		if ($this->iteratorPos % 6 == 0) { 
    	return true; 
    	}
	}
	
	function GroupNum() { 
		return floor($this->iteratorPos / 6) + 1; 
	}

When I attempt to load this page, I get the following error:

Parse error: syntax error, unexpected T_RETURN in /home/homewerx/mamasapronstrings/mysite/code/Product.php on line 64

(Product.php is the child page). Line 64 is the "return true" in function Grouping(). Any thoughts about this?

Thanks so much again! :D

Avatar
UncleCheese

Forum Moderator, 4102 Posts

6 February 2009 at 8:24am

try

   function Grouping() {
      return $this->iteratorPos % 6 == 0;
   } 

Avatar
BLU42 Media

Community Member, 71 Posts

6 February 2009 at 3:14pm

The unexpected return could be from an open bracket above... it's not an issue in the function. Double-check everything before line 64 (yippee!)

For the Children set, you could try putting this function in your page:

function MyChildren() {
	return DataObject::get(
		'ChildPageType',
		"`ParentID` = '$this->ID'",
		'Sort'
	)
}

Then, in your template use <% control MyChildren %>

Any luck??

-John

Avatar
Boogiez

Community Member, 17 Posts

6 February 2009 at 10:05pm

Ack, still no luck. I made the change UncleCheese suggested and the page would then load. However, the output was completely missing the <div id="group#"> and </div> tags - all of the children just appeared. I suspected that the functions weren't being called for some reason so I tried creating my own function in Product.php (the child page) and could not get any function to work at all! Very strange.

My test was something simple like:

	function testfunc() { 
		return 5; 
	}

and I called it in the page (within the <% control Children %> block with:
$testfunc

Nothing appears! So it seems that I may be having problems beyond this. I did try adding the MyChildren function to the controller of the parent page (ProductGallery.php) and now I get a "syntax error, unexpected T_RETURN... in ProductGallery.php on line 66". Line 66 is the return statement for the MyChildren function.

I guess the question has now shifted to why can't get a simple function to work. :( I will see if I can figure this out first. Thanks again for all your help!

Avatar
BLU42 Media

Community Member, 71 Posts

7 February 2009 at 3:04am

If you want, post or attach the whole page and we'll take a look.

-John

Avatar
Boogiez

Community Member, 17 Posts

7 February 2009 at 7:52am

Edited: 07/02/2009 7:53am

Good news! :D I got it working. I removed everything that I had added and readded it, but erased all of the whitespace and retyped it (I suspect that there's some issue with my text encoding). Now, the only problem is that there seems to be some issue with the logic itself. Here's the output when I have 8 children (all snippets of titles from my bookshelf :)):

		<div id="group1">
	
	<p>Child: Information Science</p>
	
		</div>
	
	<p>Child: Bicycle Manual</p>
	

	
	<p>Child: Data Structures</p>
	

	
	<p>Child: Apple T-Shirts</p>
	

	
	<p>Child: Java Abstractions</p>
	

	
	<p>Child: Smart Cornell</p>
	

	
		<div id="group2">
	
	<p>Child: Learning Yiddish</p>
	
		</div>
	

	
	<p>Child: Water Bottle</p>
	
		</div>

So the problem seems to be that the </div> is inserted right after the first element in each group, not after the last element in the group. Since I'm using this in my template:

<% control MyChildren %>
	<% if Grouping %>
		<div id="group{$GroupNum}">
	<% end_if %>
	<p>Child: $Title</p>
	<% if Grouping || Last %>
		</div>
	<% end_if %>
<% end_control %>

This incorrect result makes sense, unless I don't properly understand how the function works. I'm gonna try to figure out the logic to fix this... let me know if you have any suggestions :)

Go to Top