Skip to content

Commit 54deeb0

Browse files
afboradistantnative
authored andcommitted
New translations root
1 parent 93e92a1 commit 54deeb0

File tree

6 files changed

+202
-48
lines changed

6 files changed

+202
-48
lines changed

config/areas/languages/views.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
$language = Find::language($code);
1717
$link = '/languages/' . $language->code();
1818
$strings = [];
19-
$foundation = $kirby->defaultLanguage()->translations();
20-
$translations = $language->translations();
19+
$foundation = $kirby->defaultLanguage()->translations()->toArray();
20+
$translations = $language->translations()->toArray();
2121

2222
ksort($foundation);
2323

src/Cms/AppTranslations.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ protected function i18n(): void
3131
$this->multilang() === true &&
3232
$language = $this->languages()->find($locale)
3333
) {
34-
$data = [...$data, ...$language->translations()];
34+
$data = [
35+
...$data,
36+
...$language->translations()->toArray()
37+
];
3538
}
3639

3740

@@ -135,7 +138,10 @@ public function translation(string|null $locale = null): Translation
135138

136139
// inject current language translations
137140
if ($language = $this->language($locale)) {
138-
$inject = [...$inject, ...$language->translations()];
141+
$inject = [
142+
...$inject,
143+
...$language->translations()->toArray()
144+
];
139145
}
140146

141147
// load from disk instead
@@ -161,7 +167,7 @@ public function translations(): Translations
161167
if ($languages = $this->languages()) {
162168
foreach ($languages as $language) {
163169
$languageCode = $language->code();
164-
$languageTranslations = $language->translations();
170+
$languageTranslations = $language->translations()->toArray();
165171

166172
// merges language translations with extensions translations
167173
if (empty($languageTranslations) === false) {

src/Cms/Core.php

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -316,33 +316,34 @@ public function load(): Loader
316316
public function roots(): array
317317
{
318318
return $this->cache['roots'] ??= [
319-
'kirby' => fn (array $roots) => dirname(__DIR__, 2),
320-
'i18n' => fn (array $roots) => $roots['kirby'] . '/i18n',
319+
'kirby' => fn (array $roots) => dirname(__DIR__, 2),
320+
'i18n' => fn (array $roots) => $roots['kirby'] . '/i18n',
321321
'i18n:translations' => fn (array $roots) => $roots['i18n'] . '/translations',
322-
'i18n:rules' => fn (array $roots) => $roots['i18n'] . '/rules',
323-
324-
'index' => fn (array $roots) => static::$indexRoot ?? dirname(__DIR__, 3),
325-
'assets' => fn (array $roots) => $roots['index'] . '/assets',
326-
'content' => fn (array $roots) => $roots['index'] . '/content',
327-
'media' => fn (array $roots) => $roots['index'] . '/media',
328-
'panel' => fn (array $roots) => $roots['kirby'] . '/panel',
329-
'site' => fn (array $roots) => $roots['index'] . '/site',
330-
'accounts' => fn (array $roots) => $roots['site'] . '/accounts',
331-
'blueprints' => fn (array $roots) => $roots['site'] . '/blueprints',
332-
'cache' => fn (array $roots) => $roots['site'] . '/cache',
333-
'collections' => fn (array $roots) => $roots['site'] . '/collections',
334-
'commands' => fn (array $roots) => $roots['site'] . '/commands',
335-
'config' => fn (array $roots) => $roots['site'] . '/config',
336-
'controllers' => fn (array $roots) => $roots['site'] . '/controllers',
337-
'languages' => fn (array $roots) => $roots['site'] . '/languages',
338-
'license' => fn (array $roots) => $roots['config'] . '/.license',
339-
'logs' => fn (array $roots) => $roots['site'] . '/logs',
340-
'models' => fn (array $roots) => $roots['site'] . '/models',
341-
'plugins' => fn (array $roots) => $roots['site'] . '/plugins',
342-
'sessions' => fn (array $roots) => $roots['site'] . '/sessions',
343-
'snippets' => fn (array $roots) => $roots['site'] . '/snippets',
344-
'templates' => fn (array $roots) => $roots['site'] . '/templates',
345-
'roles' => fn (array $roots) => $roots['blueprints'] . '/users',
322+
'i18n:rules' => fn (array $roots) => $roots['i18n'] . '/rules',
323+
324+
'index' => fn (array $roots) => static::$indexRoot ?? dirname(__DIR__, 3),
325+
'assets' => fn (array $roots) => $roots['index'] . '/assets',
326+
'content' => fn (array $roots) => $roots['index'] . '/content',
327+
'media' => fn (array $roots) => $roots['index'] . '/media',
328+
'panel' => fn (array $roots) => $roots['kirby'] . '/panel',
329+
'site' => fn (array $roots) => $roots['index'] . '/site',
330+
'accounts' => fn (array $roots) => $roots['site'] . '/accounts',
331+
'blueprints' => fn (array $roots) => $roots['site'] . '/blueprints',
332+
'cache' => fn (array $roots) => $roots['site'] . '/cache',
333+
'collections' => fn (array $roots) => $roots['site'] . '/collections',
334+
'commands' => fn (array $roots) => $roots['site'] . '/commands',
335+
'config' => fn (array $roots) => $roots['site'] . '/config',
336+
'controllers' => fn (array $roots) => $roots['site'] . '/controllers',
337+
'languages' => fn (array $roots) => $roots['site'] . '/languages',
338+
'license' => fn (array $roots) => $roots['config'] . '/.license',
339+
'logs' => fn (array $roots) => $roots['site'] . '/logs',
340+
'models' => fn (array $roots) => $roots['site'] . '/models',
341+
'plugins' => fn (array $roots) => $roots['site'] . '/plugins',
342+
'roles' => fn (array $roots) => $roots['blueprints'] . '/users',
343+
'sessions' => fn (array $roots) => $roots['site'] . '/sessions',
344+
'snippets' => fn (array $roots) => $roots['site'] . '/snippets',
345+
'templates' => fn (array $roots) => $roots['site'] . '/templates',
346+
'translations' => null,
346347
];
347348
}
348349

src/Cms/Language.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class Language implements Stringable
4949
protected bool $single;
5050
protected array $slugs;
5151
protected array $smartypants;
52-
protected array $translations;
52+
protected LanguageTranslations $translations;
5353
protected string|null $url;
5454

5555
/**
@@ -69,14 +69,15 @@ public function __construct(array $props)
6969
$this->single = $props['single'] ?? false;
7070
$this->slugs = $props['slugs'] ?? [];
7171
$this->smartypants = $props['smartypants'] ?? [];
72-
$this->translations = $props['translations'] ?? [];
7372
$this->url = $props['url'] ?? null;
7473

7574
if ($locale = $props['locale'] ?? null) {
7675
$this->locale = Locale::normalize($locale);
7776
} else {
7877
$this->locale = [LC_ALL => $this->code];
7978
}
79+
80+
$this->translations = new LanguageTranslations($this, $props['translations'] ?? []);
8081
}
8182

8283
/**
@@ -131,7 +132,7 @@ public function clone(array $props = []): static
131132
'name' => $this->name,
132133
'slugs' => $this->slugs,
133134
'smartypants' => $this->smartypants,
134-
'translations' => $this->translations,
135+
'translations' => $this->translations->toArray(),
135136
'url' => $this->url,
136137
], $props));
137138
}
@@ -461,6 +462,7 @@ public function save(): static
461462
{
462463
try {
463464
$existingData = Data::read($this->root());
465+
$data['translations'] = $this->translations()->load($existingData['translations'] ?? []);
464466
} catch (Throwable) {
465467
$existingData = [];
466468
}
@@ -472,12 +474,19 @@ public function save(): static
472474
'direction' => $this->direction(),
473475
'locale' => Locale::export($this->locale()),
474476
'name' => $this->name(),
475-
'translations' => $this->translations(),
477+
'translations' => $this->translations()->toArray(),
476478
'url' => $this->url,
477479
];
478480

479481
ksort($data);
480482

483+
// save translations to the custom root and remove translations
484+
// to prevent duplication write into the language file
485+
if ($this->translations()->root() !== null) {
486+
$this->translations()->save($data['translations'] ?? []);
487+
$data['translations'] = [];
488+
}
489+
481490
Data::write($this->root(), $data);
482491

483492
return $this;
@@ -538,9 +547,9 @@ public function toArray(): array
538547
}
539548

540549
/**
541-
* Returns the translation strings for this language
550+
* Returns the language translations object for this language
542551
*/
543-
public function translations(): array
552+
public function translations(): LanguageTranslations
544553
{
545554
return $this->translations;
546555
}
@@ -571,7 +580,7 @@ public function update(array|null $props = null): static
571580
$updated = $this->clone($props);
572581

573582
if (isset($props['translations']) === true) {
574-
$updated->translations = $props['translations'];
583+
$updated->translations = new LanguageTranslations($updated, $props['translations']);
575584
}
576585

577586
// validate the updated language

src/Cms/LanguageTranslations.php

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
namespace Kirby\Cms;
4+
5+
use Exception;
6+
use Kirby\Data\Data;
7+
use Kirby\Filesystem\F;
8+
9+
/**
10+
* With helper methods provides get language translations or
11+
* loads from custom `translations` root
12+
* @since 5.0.0
13+
*
14+
* @package Kirby Cms
15+
* @author Ahmet Bora <[email protected]>
16+
* @link https://getkirby.com
17+
* @copyright Bastian Allgeier
18+
* @license https://getkirby.com/license
19+
*/
20+
class LanguageTranslations
21+
{
22+
protected App $kirby;
23+
protected array $data;
24+
25+
public function __construct(
26+
protected Language $language,
27+
self|array $translations = []
28+
) {
29+
$this->kirby = App::instance();
30+
$this->setTranslations($translations);
31+
}
32+
33+
/**
34+
* Returns a single translation string by key
35+
*/
36+
public function get(string $key, string $default = null): string|null
37+
{
38+
return $this->data[$key] ?? $default;
39+
}
40+
41+
/**
42+
* Loads the language translations based on custom roots for provided language code
43+
*/
44+
public function load(array $default = []): array
45+
{
46+
if ($file = static::root()) {
47+
try {
48+
return Data::read($file);
49+
} catch (Exception) {
50+
return $default;
51+
}
52+
}
53+
54+
return $default;
55+
}
56+
57+
/**
58+
* Saves the language translations in the custom root
59+
* @internal
60+
*
61+
* @return $this
62+
*/
63+
public function save(array $translations = []): static
64+
{
65+
if ($root = $this->root()) {
66+
$this->data = $translations;
67+
Data::write($root, $translations);
68+
}
69+
70+
return $this;
71+
}
72+
73+
/**
74+
* Returns custom translations root path if defined
75+
*/
76+
public function root(): string|null
77+
{
78+
$kirby = App::instance();
79+
$root = $kirby->root('translations');
80+
$file = $root . '/' . $this->language->code() . '.php';
81+
82+
if (
83+
$root !== null &&
84+
F::exists($file) === true
85+
) {
86+
return $file;
87+
}
88+
89+
return null;
90+
}
91+
92+
/**
93+
* Removes a translation key
94+
*
95+
* @return $this
96+
*/
97+
public function remove(string $key): static
98+
{
99+
unset($this->data[$key]);
100+
return $this;
101+
}
102+
103+
/**
104+
* Sets the translation key
105+
*
106+
* @return $this
107+
*/
108+
public function set(string $key, string|null $value = null): static
109+
{
110+
$this->data[$key] = $value;
111+
return $this;
112+
}
113+
114+
/**
115+
* Set translations
116+
*
117+
* @return $this
118+
*/
119+
public function setTranslations(self|array $translations = []): static
120+
{
121+
if (empty($translations) === false) {
122+
if ($translations instanceof self) {
123+
$this->data = $translations->toArray();
124+
} else {
125+
$this->data = $translations;
126+
}
127+
} else {
128+
$this->data = static::load();
129+
}
130+
131+
return $this;
132+
}
133+
134+
/**
135+
* Returns translations
136+
*/
137+
public function toArray(): array
138+
{
139+
return $this->data;
140+
}
141+
}

src/Cms/LanguageVariable.php

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public static function create(
4646

4747
$kirby = App::instance();
4848
$language = $kirby->defaultLanguage();
49-
$translations = $language->translations();
49+
$translations = $language->translations()->toArray();
5050

5151
if ($kirby->translation()->get($key) !== null) {
5252
if (isset($translations[$key]) === true) {
@@ -72,11 +72,9 @@ public function delete(): bool
7272
{
7373
// go through all languages and remove the variable
7474
foreach ($this->kirby->languages() as $language) {
75-
$variables = $language->translations();
76-
77-
unset($variables[$this->key]);
78-
79-
$language->update(['translations' => $variables]);
75+
$translations = $language->translations();
76+
$translations->remove($this->key);
77+
$language->update(['translations' => $translations]);
8078
}
8179

8280
return true;
@@ -88,7 +86,7 @@ public function delete(): bool
8886
public function exists(): bool
8987
{
9088
$language = $this->kirby->defaultLanguage();
91-
return isset($language->translations()[$this->key]) === true;
89+
return $language->translations()->get($this->key) !== null;
9290
}
9391

9492
/**
@@ -105,8 +103,7 @@ public function key(): string
105103
public function update(string $value): static
106104
{
107105
$translations = $this->language->translations();
108-
$translations[$this->key] = $value;
109-
106+
$translations->set($this->key, $value);
110107
$language = $this->language->update(['translations' => $translations]);
111108

112109
return $language->variable($this->key);
@@ -117,6 +114,6 @@ public function update(string $value): static
117114
*/
118115
public function value(): string|null
119116
{
120-
return $this->language->translations()[$this->key] ?? null;
117+
return $this->language->translations()->get($this->key);
121118
}
122119
}

0 commit comments

Comments
 (0)