I would do it the other way around as described in my previous post:
So you don’t set the other related pages on the page that represents the whole subcategory. Instead, you add the subcategory on all pages that belong to the subcategory. Basically you take a row of the table (a product page) and add every subcategory that contains an x in the table to the tags field.
Another idea that is probably more flexible in the future:
Create a page /categories.
Create a page for each category.
Create a page for each subcategory as child of the category.
Add two fields to it: A select field to select the destination page for the overview and a tags field, this time with the pages that belong to the subcategory.
Advantage: A product can be the destination for more than one subcategory and you can easily add new (sub)categories.
Disadvantage: Same problem with the tags field: You need to enter the URI of the page.
Unfortunately no. You can hide all subpages, but not a specific one.
But if the categories don’t need to be flexible and easy to change, this solution doesn’t make much sense anyway. My other suggestion doesn’t use extra pages. But: Because a page can be the destination of multiple subcategories, you will need to use two tags fields (one for the subcategories this page is destination of and one for the other subcategories) instead of one select and one tags field.
The checkboxes are simply not meant to be used for that complex and large selection structures.
Another idea came to my mind: Instead of the two tags fields, you could also use one structure field that allows 0 to n items each containing a select field to select a subcategory and a toggle to select whether this page is the destination for this category:
fields:
categories:
label: Categories
type: structure
entry: >
{{subcategory}}<br />
Destination page: {{destination}}
fields:
subcategory:
label: Subcategory
type: select
options:
...
destination:
label: Should this page be the destination page for this subcategory?
type: toggle
text: yes/no
This would be quite user-friendly and at the same time allow to make one page the destination for multiple subcategories.
i guess it’s either adding the categories and landing pages for every product page
Or the related pages for every page… since the “loesungen” already have a structure…
Forget about the “related pages”. You can get them in your template by filtering all product pages by the categories structure field. If this field contains the same category as the current page, it’s related.
It’s like with relational database systems. You can store the categories with the pages or the pages with the categories. You have to decide for one, but in this case the first makes more sense.
I integrated the structure field as proposed by @lukasbestle and attached some products to their categories and subcategories. The category options for the subcategory select field are named after the following scheme: Category/Subcategory.
Now i want to edit the front-end template and display the categories and their subcategories. The subcategories must be listed unter the categories and only appear once. Furthermore each subcategory must be a link to the regarding product page where destination = true.
Since the documentation on the structured field is a little limited i figured sth like this:
foreach ($solutions->children()->children()->index() as $solution){
// necessary information from all product pages in an array
$content = yaml($solution->categories());
...
}
i have a controller that searches the solution page, and return it as collection $solutions . But $solutions also include the substructure therefore i query children()->children() .
Thanks everyone!
Edit: my Solution so far:
<?php
// All solution pages..
$solutions;
$blocks = array();
// The sorted Categories with url and such...
foreach ($solutions->children()->children()->index() as $solution){
// Page content definded by user
$content = $solution->categories()->yaml();
// This solutions URL
$url = $solution->url();
// loop through content
foreach($content as $value){
if ($value['destination'] == 'true' ){
$categories = explode("/", $value['subcategory']);
$category = $categories[0];
$subcategory = $categories[1];
$blocks[$category][$subcategory] = $url;
}
}
}
//Print the whole thing....
foreach ($blocks as $block=>$subcategory){
echo "<div class='sm-col sm-col-12 md-col-6 lg-col-3 p2'>";
echo "<div class='p2 bg-olive'>";
echo "<h1>$block</h1>";
echo "<ul>";
foreach ($subcategory as $category => $link){
echo "<li><a href='$link'>$category</a></li>";
}
echo "</ul>";
echo "</div>";
echo "</div>";
}
?>
maybe someone has some suggestions how to do this more efficient / better? : )
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);
You will also need some code to fetch the related pages with the same subcategories. Here’s an example for that:
// Get a list of the categories of this page
$categories = $page->categories()->toStructure()->pluck('subcategories');
// Filter all solutions by the current categories
$related = $pages->index()->filterBy('template', 'solution')->filter(function($solution) use($categories) {
$solutionCategories = $solution->categories()->toStructure();
foreach($solutionCategories as $category) {
// Check if this subcategory is shared with the current page
// If yes, the pages are related
if(in_array((string)$category->subcategory(), $categories)) return true;
}
// No match, no relation
return false;
});
Perfect, so i got everything working as it was supposed to,
i got one last question though:
I need to have an english translation for the Categories/SubCategories, where could i add those?
Inside the language folder? What would be the key? Would it be the value saved in the blueprint?
Btw. here is the code i used for the related pages: maybe some tips, where i could be more efficient?
// Get a list of the categories of this page
$filter = urldecode(param('filter'));
$related = array();
if (!is_null($filter)){
$solutions = $pages->index()->filterBy('template', 'solutions');
foreach ($solutions as $solution){
$Categories = $solution->categories()->toStructure()->pluck('subcategory');
foreach ($Categories as $category){
// this still looks ugly xD
list($mainCategory, $subCategory) = explode("/", $category);
if ($filter == $subCategory){
$related[] = $solution;
}
}
}
}