Your code looks like a quite good start.
You can however also filter by template instead of limiting to a specific parent page:
foreach ($solutions->index()->filterBy('template', 'solution') as $solution) {
...
This will get all pages (even sub-sub-sub-pages of $solutions
), but only those that use the template solution.php
.
In the loop you then need to iterate through the items from the structure field and build an index of the categories. Here’s some untested example code:
Controller code
$categories = array();
foreach ($solutions->index()->filterBy('template', 'solution') as $solution) {
$solutionCategories = $solution->categories()->toStructure();
foreach($solutionCategories as $category) {
list($mainCategory, $subCategory) = explode('/', $category->subcategory());
// Add sub category to array
if(!isset($categories[$mainCategory][$subCategory])) {
$categories[$mainCategory][$subCategory] = false;
}
// Set page if set to be destination
// Check whether a destination has already been set (makes sure the first match is being used)
if($category->destination() === 'true' && $categories[$mainCategory][$subCategory] === false) {
$categories[$mainCategory][$subCategory] = $solution;
}
}
}
// Sort columns alphabetically
ksort($categories);
Template code
// Print columns and rows
foreach($categories as $mainCategory => $subCategories) {
// Pseudo markup
echo '<column>' . $mainCategory;
// Sort rows alphabetically
ksort($subCategories);
foreach($subCategories as $subCategory => $destination) {
echo '<row><a href="' . $destination->url() . '">' . $subCategory . '</a></row>';
}
echo '</column>';
}
Edit: Oh, you were faster. I hope my example helps you anyway.