For a multi language category selection I need to translate the text of a select field in the panel. My first try was to just wrap the category like text: "{{ t(structureItem.category) }}" But this unfortunately doesn’t work. Is there any other way to do this?
What I really wanted to achieve is a multi language blog with translated categories.
My first idea was to have one category structure per language:
categories:
type: fields
fields:
categories:
label: Verfügbare Kategorien
type: structure
fields:
category:
label: Kategorie
type: text
But then I would have needed a translation mapping (in a kirby language file / from keys to either german or english) somewhere and the editor wouldn’t have direct access to the categories without me. For that I also needed the translation from the category keys to the category name of the selected panel language (that was my reason to post the question).
I now have the mapping in one not translatable structure field:
categories:
type: fields
fields:
categories:
label: Verfügbare Kategorien
type: structure
translate: false
fields:
category:
label: Kategorie
type: text
categoryEn:
label: Kategorie (english)
type: text
And the translation happens on demand in a page controller:
return function($page) {
$isEnglishActive = kirby()->language()->code() === 'en';
// filter articles for current language only
$articles = $page->children()->listed()->sortBy('date', 'desc');
$articles = $articles->filter(function ($child) {
return $child->translation(kirby()->language()->code())->exists();
});
// set all categories used by articles
$usedCategories = array_unique($articles->pluck('category'));
// filter articles by current category
if ($category = param(kirby()->option('category_param'))) {
$articles = $articles->filter(function ($article) use ($category) {
return $article->category()->slug()->toString() === Str::slug($category);
});
}
if ($isEnglishActive) {
$availableCategories = page(kirby()->option('category_page_id'))->categories()->toStructure();
$availableCategoriesDe = $availableCategories->pluck('category');
$availableCategoriesEn = $availableCategories->pluck('categoryen');
$availableCategoriesDictionary = array_combine($availableCategoriesDe, $availableCategoriesEn);
// use english category names if current language is english
$categories = array_map(function ($category) use ($page, $availableCategoriesDictionary) {
return $category = array(
'name' => $availableCategoriesDictionary[$category->category()->toString()],
'url' => getCategoryUrl($page->url(), $category)
);
}, $usedCategories);
}
else {
// use german category names (default)
$categories = array_map(function ($category) use ($page) {
return $category = array(
'name' => $category->category()->toString(),
'url' => getCategoryUrl($page->url(), $category)
);
}, $usedCategories);
}
return compact('articles', 'categories');
};
Now I’m pretty happy that it works, but I’m not sure if it could be any better or more kirby-like?
For the Panel part of it, I’d choose another approach.
Blueprint setup for structure field in parent page (or whereever you are keeping this)
categories:
type: structure
translate: false
fields:
key:
type: text
de:
type: text
label: German
en:
type: text
label: English
Select field setup with custom field method to fetch translation for the text, passing in the field name as param make the function more versatile, because we don’t have to hardcode the structure field fieldname inside the method.
Hello @texnixe, I was wondering if with Kirby 3.9 this is still the best way to approach querying a structure field for multi-language select options then using the correct translation in the front-end?
I understand that instead of fetch, I should now use:
options:
type: query
Is there anything else that would be good to update to make use of of 3.9 updates?
I understand structure items aren’t assigned UUIDs out of the box, correct? I can always use the AutoID plugin to avoid the “key” field.