hello everyone. new topic today. i want my users to be able to switch their panel language (not content language) to only 2 options, since all our yamls are only in two languages and kirby offers by default a lot more languages. can this easily be done? i could not find any info to achieve this. thank you!
You could try removing unwanted languages from /kirby/i18n/translations
.
But then that would be overwritten every time you update.
I think it would be a better option to overwrite the account view, to be specific, the user.changeLanguage dialog and replace
Field::translation(['required' => true])
with something custom.
Or maybe easier: Use a custom Kirby instance and overwrite the translations()
method (I guess you should not want to use other languages in the frontend in that case either), Replacing core classes | Kirby CMS
thank you both! i guess for the time being and since it is a non-critical feature i would go with just removing the translations, but i will check the translations() function when i get the time and see what exactly i have to remove there
i just checked out your solution. somehow i think translations() only refers to the translations in the languages files (de.php, en.php, etc) but not the actual panel languages. i am logging the arrays inside the function and i am getting only like 6-7 languages, defined by me or plugins.
i am trying to overwrite this function
<?php
// give it a namespace, not required but good practice
namespace cookbook\core;
// import App class
// (so that we don't have to use fully-qualified class names all over the place)
use Kirby\Cms\App as Kirby;
use Kirby\Cms\Languages;
use Kirby\Cms\Translation;
use Kirby\Cms\Translations;
use Kirby\Filesystem\Dir;
use Kirby\Filesystem\F;
use Kirby\Toolkit\Str;
class CustomKirby extends Kirby
{
public function translations(): Translations
{
if ($this->translations instanceof Translations) {
return $this->translations;
}
$translations = $this->extensions['translations'] ?? [];
// injects languages translations
if ($languages = $this->languages()) {
foreach ($languages as $language) {
$languageCode = $language->code();
$languageTranslations = $language->translations();
// merges language translations with extensions translations
if (empty($languageTranslations) === false) {
$translations[$languageCode] = array_merge(
$translations[$languageCode] ?? [],
$languageTranslations
);
}
}
}
return $this->translations = $this->loadTranslations($this->root('i18n:translations'), $translations);
}
public function loadTranslations(string $root, array $inject = []): Translations
{
$collection = new Translations();
foreach (Dir::read($root) as $filename) {
if (F::extension($filename) !== 'json' || !in_array($filename, ['de.json', 'en.json'])) {
continue;
}
$locale = F::name($filename);
$translation = Translation::load($locale, $root . '/' . $filename, $inject[$locale] ?? []);
$collection->data[$locale] = $translation;
}
return $collection;
}
}
thank you sonja! this works perfectly to make it more dynamic i changed the loadTranslations function a bit.
public function loadTranslations(string $root, array $inject = []): Translations
{
// for dynamic loading of the langs being used in the panel
$active_languages = [];
foreach (kirby()->languages() as $lang) {
array_push($active_languages, $lang . '.json');
}
$collection = new Translations();
foreach (Dir::read($root) as $filename) {
if (F::extension($filename) !== 'json' || !in_array($filename, $active_languages)) { // for dynamic loading of the langs being used in the panel
continue;
}
$locale = F::name($filename);
$translation = Translation::load($locale, $root . '/' . $filename, $inject[$locale] ?? []);
$collection->data[$locale] = $translation;
}
return $collection;
}