groupBy "kills" the spelling of the grouped by field

Good evening

I use

page('faq')->children()->groupBy('category');

to get a Collection which I loop through to create a submenu like navigation.

The problem is that when doing it like this, the category field of a page changes from “An Example” to “an example”. To be precise: in my content.txt the field looks like this:

Category: An Example

But using the code above, the output is “an example”.

Using Str::Camel or something like this does not work because I have spaces and hypens in the category name.

Any idea how I can fix this?

Thanks
Andreas

That’s indeed an issue with the group method. Theoretically, you should be able to pass a second $i argument (as false) to prevent lowercasing, but then the method breaks, because you don’t have a string anymore.

So I guess this is a bug.

Maybe you can work around by with a custom pages method.

Basically, copy the group method in a plugin:

	'collectionMethods' => [
		'customGroup' => function ($field, bool $i = true) {

				if (is_string($field) === true) {
					$groups = new Collection([], $this->parent());

					foreach ($this->data as $key => $item) {
						$value = $this->getAttribute($item, $field);
						// make sure that there's always a proper value to group by
						if (!$value) {
							throw new InvalidArgumentException('Invalid grouping value for key: ' . $key);
						}

						// ignore upper/lowercase for group names
						if ($i) {
							$value = Str::lower($value);
						} else {
							$value = $value->value();
						}

						if (isset($groups->data[$value]) === false) {
							// create a new entry for the group if it does not exist yet
							$groups->data[$value] = new static([$key => $item]);
						} else {
							// add the item to an existing group
							$groups->data[$value]->set($key, $item);
						}
					}

					return $groups;
				}

				return parent::group($field, $i);
			}
	]

Then

<?php  foreach (page('faq')->children()->customGroup('category', false) as $key => $items) {}

Thanks @texnixe but for me there is a simplier solution:

ucwords($category, " \t\r\n\f\v\-")

This Upper-Cases every word in a category, including spaces etc and also if a hypen is used such as “Managed-Services”

Andreas

PS: Finally I found a bug in Kirby!! :smile:

The issue with the lower-cased grouping values will be fixed in the next release (3.9.7)

There is also an issue that it doesn’t play nice with international characters like ÅÄÖ.

Hm, I cannot reproduce that issue. Can you describe the issue in more detail, please. Kirby version, environment, etc.

Turns out I can’t reproduce it now either on the site on which I used to have this issue. I’m pretty certain it used to be a problem, because I had to resort to “translate” the group return values in a switch statement. Likely something in my environment changed, or it was fixed in a Kirby update since then. I’m now on 3.7.5, PHP 8.1.13, Apache and all is good.


On a sidenote. I just did notice one funny thing regarding the lower casing though. Characters with umlauts always preserves the original case while non-umlaut characters don’t. B

return $text = 'A year'; //will output: a year

while…

return $text = 'Á year'; //will output: Á year

Please check if this is still the case with an up-to-date version of Kirby, we don’t fix old versions.