Hi, I saw here: https://getkirby.com/docs/quicktips/language-variables, that you can read translations from external files. I was wondering if it’s also possible to write to external files? Currently, if you read from an external file and change a translation in the panel, the entire translation array gets replaced.
The reason we prefer translations to be separate is that we want them to be ignored by git.
No, that’s currently not possible, I think there is a feature request already somewhere.
Okay and I see that it’s on the roadmap for kirby 5!
Not officially.
Unofficially, in a plugin, you could override the dialogs that store the data.
Here’s an example implementation that stores the data in a yaml file in a “vars” directory (like the quick tip). You could adjust it so that it does the right thing for you.
<?php
use Kirby\Cms\App;
use Kirby\Data\Data;
use Kirby\Filesystem\F;
class TranslationsStore {
protected $cache;
public function __construct(protected readonly string $language) {
$this->cache = null;
}
public function root() {
return kirby()->root('languages') . "/vars/{$this->language}.yml";
}
public function fetch(): array {
if($this->cache !== null) {
return $this->cache;
}
$root = $this->root();
if(file_exists($root)) {
$this->cache = Data::decode(F::read($root), 'yaml');
} else {
$this->cache = [];
}
return $this->cache;
}
protected function store(array $arr) {
$filename = $this->root();
$this->cache = $arr;
F::write($filename, Data::encode($arr, 'yaml'));
}
public function create(string $key, string $value):void {
$arr = $this->fetch();
$arr[$key] = $value;
$this->store($arr);
}
public function delete(string $key):void {
$arr = $this->fetch();
unset($arr[$key]);
$this->store($arr);
}
public function update(string $key, string $value):void {
$arr = $this->fetch();
$arr[$key] = $value;
$this->store($arr);
}
}
App::plugin('lol/lol', [
'areas' => [
'languages' => fn(App $kirby) => [
'dialogs' => [
'language.translation.create' => [
'submit' => function(string $code) use ($kirby) {
$request = $kirby->request();
$store = new TranslationsStore($code);
$store->create($request->get('key'), $request->get('value', ''));
return true;
}
],
'language.translation.delete' => [
'submit' => function(string $code, string $translationKey) {
$store = new TranslationsStore($code);
$key = rawurldecode(base64_decode($translationKey));
$store->delete($key);
return true;
}
],
'language.translation.update' => [
'submit' => function(string $code, string $translationKey) use ($kirby) {
$request = $kirby->request();
$store = new TranslationsStore($code);
$key = rawurldecode(base64_decode($translationKey));
$store->update($key, $request->get('value', ''));
return true;
}
]
]
],
]
]);