Sort pages collection by a field in the first child of each of the pages in the collection

#1

Is this actually possible?
To sort a pages collection by a field in the first child of each of the pages?

Thank you

#2

Pretty sure you can chain filters onto a collection. If you make a collection that gets all of the pages, then in your template you should be able to do something like:

$filterset = $kirby->collection('yourcollection'); // all of the pages
$filterdata = $filterset->first()->yourField(); // get the value you want to filter on
$filterresult = $filterset->filterby('yourField', $filterdata); // use that value in a filter

Then you can do a foreach on $filterresult etc

#3

Assuming that you have already made sure the pages in your collection ($collection) all have children (otherwise you have to filter them first or apply a condition that makes sure you don’t run into an error when calling first()):

$filtered = $collection->filter(function($p) {
  return $p->children()->first()->fieldname()->value() === 'whatever';
}
#4

Thank you both. As far as I can tell @texnixe’s answer is about filtering pages in a collection by the value of a field in their first child. But I asked for sorting pages by a field in the first child.

I was hoping for something simple such as

$pageCollection.sortBy($page->child()->first()->field())

But as there is probably nothing like that I ended up using site/collections.
The code creates a new pages collection with the first child of each of the pages I want to sort (actually the last child), sorts these children by a publicationDate field, and then uses that same order to append each of their parents to the final page collection I return.

<?php

return function ($site) {
	$sortedProgrammes = new Pages();
	$theChildren = new Pages();
	foreach($site->children()->filterBy('intendedtemplate', 'programme')->listed() as $p) {
		if($p->hasChildren()) {
			$theChildren->append($p->children()->last());
		}
	}
	$theChildren = $theChildren->sortBy('publicationDate', 'desc');
	foreach($theChildren as $c) {
		$sortedProgrammes->append($c->parent());
	}
	return $sortedProgrammes;
};

Please feel free to comment this solution.

Thank you

#5

Oh sorry, I didn’t read properly. The sortBy() function also accepts a callable…

1 Like