Hi dear community
I’m currently working on an multi-language portfolio where projects have categories acting as filters. I needed a way to manage all those categories in one place in the panel, so when some are renamed for example, I don’t have to manually update each project page where they could have already been attributed.
In order to do this, I created a structure field in a Projects blueprint that stores all the category names in English and French, with custom UUIDs generated by a hook on page update.
Here is the blueprint:
categories:
label: Categories
type: structure
translate: false
fields:
category:
label: English
type: text
categorie:
label: Français
type: text
uuid:
type: hidden
Here is the hook in the config.php
:
'page.update:after' => function ($newPage, $oldPage) {
if ($newPage->intendedTemplate()->name() == 'projects') {
$categories = $newPage->categories()->yaml();
foreach($categories as &$cat) {
if (!isset($cat["uuid"]) || !$cat["uuid"]) {
$cat["uuid"] = 'cat' . substr(str_replace('-', '', Str::uuid()), 0, 8);
}
}
$newPage->update(['categories' => Data::encode($categories, 'yaml')]);
}
}
And here is how everything is stored:
-
category: Exhibition
categorie: Exposition
uuid: catdcdb7f16
-
category: Graphic design
categorie: Graphisme
uuid: cat87d09ebe
Then in a Project blueprint, I added this multiselect field querying the structure:
categories:
label: Categories
type: multiselect
translate: false
options:
type: query
query: page.parent.categories.toStructure
text: "{{ item.category }}"
value: "{{ item.uuid }}"
Which stores selected UUIDs like:
Categories: catdcdb7f16, cat87d09ebe
I reeeeally don’t know if it’s the best solution to do so, but right now, it seems to work in the panel… However, I miss the solution to simply retrieve the category names based on the UUIDs on the front, depending on the language displayed, so let’s say:
$page->categoryname();
// outputs ‘Exhibition / Graphic design’ or ‘Exposition / Graphisme’
$page->categoryclass();
/* outputs ‘exhibition graphic-design’ or ‘exposition graphisme’ */
I’ve created a Project model with public functions… but well… I’m stuck here. I don’t know how to code this properly, if map functions should be used (if yes, how?), if I should go with a foreach loop on the structure and findBy('uuid', $this->categories())
. Here is what I have at the moment, after maaaany attempts (please don’t judge me ):
public function categoryname() {
$language = kirby()->language();
$allcategories = $this->parent()->categories()->toStructure();
$projectcategories = $this->categories()->split(',');
if($language == 'fr'){
$projectcategories =
}
else {
$projectcategories =
}
$categoryname = implode(' / ', $projectcategories);
return $categoryname;
};
Could someone help me please?