OK, expanding from my other thread, how do I group child pages by the value of a field in a structure field? I’ve read Grouping collections | Kirby CMS and Fetching field options | Kirby CMS but none of these seem to apply to my use case.
So, for context: I have a list of category names and “slugs” stored in a structure field on the parent page:
kategorien:
type: structure
label: Kategorien
fields:
name:
type: writer
nodes: false
marks:
- bold
- italic
help: Der öffentlich sichtbare Name der Kategorie; Textformatierungen sind möglich.
required: true
kategorie_id:
type: text
label: ID
help: Reiner Text, nur Kleinbuchstaben, Zahlen, Unter- und Bindestriche erlaubt.
required: true
On child pages, there is a select to select the appropriate category:
kategorie:
type: select
required: true
options:
type: query
query: page.parent.kategorien.toStructure
text: "{{ item.kategorie_id }}"
value: "{{ item.kategorie_id}}"
In the template on the parent page, I want to group by category and show the formatted category name as heading but I’m stuck on how to achieve this. I tried:
$kategorien = $page->children()->listed()->group(function($kategorie) {
$kat = $kategorie->kategorie();
return $kat;
});
but that only returns an array with the category ID because that’s how it’s saved according to the child page blueprint. I can’t use the formatted value in the select, though, because select options can only have plain text. So, how would I get the content of the category name field on the parent page?
You don’t group by the structure field value, but by the value stored in the kategorie
field (kategorie_id), like normal, then when rendering the value, you fetch the name
that corresponds to that value from the structure field (findBy)
Sorry, I think there is a slight misunderstanding. I can group the pages alright but getting the category name for the group headings is the issue. As far as I can see, there is no findBy()
method for structure fields. This is the structure field array when doing $page->kategorien()->yaml()
:
Array
(
[0] => Array
(
[name] => <strong>my</strong><em>formatted</em><strong>text</strong></p>
[kategorie_id] => kategorie_1
)
[1] => Array
(
[name] => <p><strong>my</strong><em>other</em><strong>category</strong></p>
[kategorie_id] => kategorie_2
)
)
I guess I need to access the name field value of the structure field inside the category loop to print that value, but unfortunately the structure field array isn’t really an associative array and my PHP knowledge is limited.
This returns an array which you cannot access with findby, if you use toStructure()
you get a collection which you can search with findBy
Thanks, after a lot of brain racking and hair pulling I finally got it. I didn’t even know a $structure
object/class exists, I never got into these corners of the documentation, let alone understand anything. This is something I’ll sit in front of next time, having forgotten everything and having to start from zero again when I look at this in a year from today.
For reference, this is the solution:
$kategorien = $page->kategorien()->toStructure();
$gruppen = $page->children()->listed()->groupBy('kategorie');
foreach($gruppen as $kategorie => $unterseiten):
$kategoriename = $kategorien->findBy('kategorie_id', $kategorie)->name();
…
echo($kategoriename);