Kirby 2.3 group(callback) -> function

Hi there,
did anybody already experimented with the new group-function?
I’d like to group projects by category, which can be more than one per project (like tags).

There are no examples for this in https://getkirby.com/docs/toolkit/api/collection/group

So, i would like to do something like this:

$category = $works->children()->visible()->group(function($categories) {
	return ( group by $value, separated by ',' sort asc)
	}); 

is that possible? and as we are at it: is it possible to use a global value for the group by value?
For example: when you have a param (year or category) in the url this could be used within the grouping function. Like: $page->$param because $page->param() would search for a textfield called param:

Thanks (as always)
Matthias

Each item can only have one group, so you currently can’t put each project into all of their respective categories, only in one.

What you could do is to pluck() all possible category values, iterate through them and then filter the matching projects:

<?php foreach($works->children()->visible()->pluck($value) as $category): ?>
  <h2><?= $category ?></h2>
  <?php foreach($works->children()->visible()->filterBy($value, $category, ',') as $project): ?>
    ...
  <?php endforeach ?>
<?php endforeach ?>

Warning: Please don’t allow $value to be set by the visitor (in the URL) without validation. Otherwise users could call the writing methods like sort() or hide(). Only allow $values from a whitelist.

Hi Lukas and thanks,
i thought that the group() function could be able to have one item in several groups.
I managed to find a workaround with pluck() as you suggested, but i am struggling with the injection of a value:

<?php 
$param = param('by'); 
$values = $page->children()->pluck($param, ',', true);
?>

$param is in this case “year” or “category”
… after the first iteration through the $values

<?php $catworks = $works->filter(function($child) use ($value) {
	return in_array($value, $child->$param->split());
	}); 
?>

I will use a whitelist later on, but for now i can’t figure out how to use a previously defined value ($param) to create something like: $child->year()->split()…

Matthias

You have to use the variable as a method and $param is not known in your filter callback, so you need to pass that to use() as well:

<?php $catworks = $works->filter(function($child) use ($value, $param) {
	return in_array($value, $child->$param()->split());
	}); 
?>

Nice!
Thanks a lot. That works. I didn’t get the declaration part…

As I wrote above, make sure to validate the param though, otherwise you will have a security issue!

done & dusted.
i have a whitelist of values that i check against, so all other values will returned to a default page.

thanks again