Reputation: 455
I'm trying to loop through all my ProductPage
s while grouping them by their grandparent's title (as this is the product category). I would also like to sort the product pages under each group by their ProductReleaseDate
descending. Finally if possible, any that do not have a ProductReleaseDate
to be listed first before everything.
I have this function in my page controller that grabs all the product pages:
function ProductPages() {
$productPages = ProductPage::get();
return $productPages ? $productPages : false;
}
Then in my template:
<% loop $ProductPages.Sort(ProductReleaseDate, DESC) %>
$Title
<% end_loop %>
This displays all my product pages titles in descending order by the ProductReleaseDate they have been given. They now need grouping.
I've been searching hard and can't find the right documentation or examples to get this right. Perhaps I need groupBy? I'm not sure if it needs to be in the controller or the template.
This may help but I need help: http://docs.silverstripe.org/en/developer_guides/model/how_tos/grouping_dataobject_sets/
Upvotes: 3
Views: 763
Reputation: 15794
In SilverStripe 3.1 we can do this with the GroupedList
, the one you linked to in your question.
To set it up we first need something to group the items by. Either a variable or a function that returns a value.
In your case we will set up a get function that returns the grand parent title.
ProductPage.php
class ProductPage extends SiteTree {
public function getGrandParentTitle() {
$parent = $this->Parent();
if ($parent->Exists()) {
$grandParent = $parent->Parent();
if ($grandParent->Exists()){
return $grandParent->Title;
}
}
return '';
}
}
Then we need to add a function that will return a GroupedList
.
Page.php
class Page extends SiteTree {
public function getGroupedProducts() {
return GroupedList::create(ProductPage::get()->sort('ProductReleaseDate', 'DESC'));
}
}
Lastly in our template we called our GroupedList
function and tell it what to group the items by.
Your template
<% loop $GroupedProducts.GroupedBy(GrandParentTitle) %>
<h3>$GrandParentTitle</h3>
<ul>
<% loop $Children %>
<li>$Title</li>
<% end_loop %>
</ul>
<% end_loop %>
Or if you want to sort by the parent page title first we will set up a get function that returns the parent title.
ProductPage.php
class ProductPage extends SiteTree {
public function getParentTitle() {
$parent = $this->Parent();
if ($parent->Exists()) {
return $parent->Title;
}
return '';
}
}
Then in our template we called our GroupedList
function that we created before but this time set GroupedBy
to ParentTitle
.
Your template
<% loop $GroupedProducts.GroupedBy(ParentTitle) %>
<h3>$ParentTitle</h3>
<ul>
<% loop $Children %>
<li>$Title</li>
<% end_loop %>
</ul>
<% end_loop %>
Upvotes: 3