SilverStripe 3: Loop greatgrandchildren pages WITH OUT grouping by parent

632 views Asked by At

In my template I'm looping my child pages as 2 separate lists and then their grandchild pages under these. But I want these greatgrandchild pages to be sorted as an entire list and not divided / grouped by their parents. Simply loop after loop does not work as all greatgrandchild pages should be put in order and not grouped by parent then sorted.

I know this could be done by a function to get all the greatgrandchildpages and sort them by a chosen method (e.g. alphabetically). But I don't want to get ALL of them as I need them just the grandchildren for each child.

PAGE - to show list

Child - List Heading

GrandChild - not shown in list

GreatGrandChild - Listed and ALL sorted Alphabetically

2

There are 2 answers

5
wmk On BEST ANSWER

On Page you can get the IDs of all children (which are parents of the grand children) using getIDList():

$ids = Page::get()->filter(array('ParentID' => $this->ID))->getIDList();

Now you can get all Pages (or whatever pagetype you want) by ParentID:

$grandChildren = Page::get()->filter(array('ParentID' => $ids));

Same for grand-grandchildren....

$grandGrandChildren = Page::get()->filter(array('ParentID' => $grandChildren->getIDList()));

You can sort this DataList by whatever you want, e.g.

$sortedgrandGrandChildren = $grandGrandChildren->sort('Title', 'ASC');

edit:

$this->Children() does return an ArrayList, not a DataList, so we have to get all children manually. Be aware, this doesn't respect canView(), so we get all pages, if the current user has permissions or not. For a simple website this should be ok.

Using $this->Children()->column('ID') you get the filtered result.

A ready to use method could be:

public function getGrandGrandChildren() {
    $ids = Page::get()->filter(array('ParentID' => $this->ID))->getIDList();
    $grandChildren = Page::get()->filter(array('ParentID' => $ids));
    $grandGrandChildren = Page::get()->filter(array('ParentID' => $grandChildren->getIDList()));

    return $grandGrandChildren->sort('Title', 'ASC');
}

And in your template:

<% loop $GrandGrandChildren %>
    <a href="$Link">$Title</a>
    //do whatever you want
<% end_loop %>
2
user4996977 On

SiteTree::get()->filter('ParentID',SiteTree::get()->filter('ParentID',$this->Children()->column('ID')))->filterByCallback(function($page){return $page->canView()})