$pages->groupBy($field) syntax

I have a page in which I collect reports as sub-pages. Amongst other fields, those reports have a field called ‘year’. As I want to display some information in per-year blocks, I wanted to use the groupBy method like this:

$reports = $page->children()->visible()->groupBy('year');
foreach ($reports as $group):
    foreach ($group as $report):
        // display some stuff
    endforeach;
endforeach;

However that. does not work. Instead I get an exception with the message “You cannot group by arrays or objects”. I found an issue on GitHub stating “$pages->groupBy($field) doesn’t work on pages?”.

So, what’s the matter with this? Is my code wrong or is there actually a bug in the toolkit?

I think it is still a bug (or simply missing functionality), which still has to be implemented in a future version of Kirby.

Would pluck do the trick? http://getkirby.com/docs/cheatsheet/files/pluck

You could use pluck()to get an array of unique years and then iterate through this array and check for each page if the condition year = x is true. That should work.

That could work. Something like (untested):

$collection = $page->children()->visible();
$years      = $collection->pluck('year', null, true);
foreach ($years as $year):
    echo '<h2>'.$year.'</h2>';
    $reports = $collection->filterBy('year', $year);
    foreach ($reports as $report):
        // display some stuff
    endforeach;
endforeach;

Thanks for all your hints and tips, I’ll give that it a try.

If this is actually not implemented, then it might be a good idea to remove it from the documentation: http://getkirby.com/docs/cheatsheet/pages/groupBy @bastianallgeier

Here’s the corresponding issue, I agree that it’s a bit confusing when offered in the docs:

Bump.

Seems that groupBy is still not working?

It should work, have you seen the docs for the correct syntax?

Seems to work, but I get this:

Invalid grouping value for key: some/page

So it’s required to have a value for every item in the groupBy collection. Maybe it would be better to just skip it if it does not exist?

Is it possible to skip items that does not have values in a kind of one-liner?

Current state

$categories = page('somepage')->children()->groupBy('category');

Not all pages have the value category.

You could filter before you group.

Yes! This seems to work:

$filtered = page('somepage')->children()->filterBy('category', '!=', '');
$categories = $filtered->groupBy('category');

Thanks! :smiley: