SilverStripe 3: How to Group a Sorted Array by Grandparents Pages
I'm trying to skip all mine ProductPage
by grouping them by their grandparents' title (since this is a product category). I would also like to sort the product pages under each group in descending order ProductReleaseDate
. Finally, if possible, any that don't ProductReleaseDate
have to be listed first before everything.
I have this function in my page controller that grabs all 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 titles in descending order with the ProductReleaseDate they got. Now they need a grouping.
I have searched a lot and cannot find the correct documentation or examples to get it right. Maybe I need a group? I'm not sure if it should be in the controller or template.
It might help, but I need help: http://docs.silverstripe.org/en/developer_guides/model/how_tos/grouping_dataobject_sets/
source to share
In SilverStripe 3.1 we can do this with the help GroupedList
you linked to in your question.
To customize it, we first need something to group the elements. Either a variable or a function that returns a value.
In your case, we'll create a get function that returns the title of the big parent.
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 GroupedList
.
page.php
class Page extends SiteTree {
public function getGroupedProducts() {
return GroupedList::create(ProductPage::get()->sort('ProductReleaseDate', 'DESC'));
}
}
Finally, in our template, we called our function GroupedList
and told it to group the elements.
Your template
<% loop $GroupedProducts.GroupedBy(GrandParentTitle) %>
<h3>$GrandParentTitle</h3>
<ul>
<% loop $Children %>
<li>$Title</li>
<% end_loop %>
</ul>
<% end_loop %>
Parent title group
Or, if you want to sort the title of the parent page first, we'll 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 function GroupedList
that we created earlier, 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 %>
source to share