1010use Kirby \Toolkit \Locale ;
1111use Kirby \Toolkit \Str ;
1212use Stringable ;
13+ use Throwable ;
1314
1415/**
1516 * The `$language` object represents
@@ -51,8 +52,8 @@ class Language implements Stringable
5152 protected bool $ single ;
5253 protected array $ slugs ;
5354 protected array $ smartypants ;
54- protected array $ translations ;
5555 protected string |null $ url ;
56+ protected LanguageVariables $ variables ;
5657
5758 /**
5859 * Creates a new language object
@@ -73,14 +74,15 @@ public function __construct(array $props)
7374 $ this ->single = $ props ['single ' ] ?? false ;
7475 $ this ->slugs = $ props ['slugs ' ] ?? [];
7576 $ this ->smartypants = $ props ['smartypants ' ] ?? [];
76- $ this ->translations = $ props ['translations ' ] ?? [];
7777 $ this ->url = $ props ['url ' ] ?? null ;
7878
7979 if ($ locale = $ props ['locale ' ] ?? null ) {
8080 $ this ->locale = Locale::normalize ($ locale );
8181 } else {
8282 $ this ->locale = [LC_ALL => $ this ->code ];
8383 }
84+
85+ $ this ->variables = new LanguageVariables ($ this , $ props ['variables ' ] ?? $ props ['translations ' ] ?? []);
8486 }
8587
8688 /**
@@ -135,7 +137,7 @@ public function clone(array $props = []): static
135137 'name ' => $ this ->name ,
136138 'slugs ' => $ this ->slugs ,
137139 'smartypants ' => $ this ->smartypants ,
138- 'translations ' => $ this ->translations ,
140+ 'variables ' => $ this ->variables -> toArray () ,
139141 'url ' => $ this ->url ,
140142 ], $ props ));
141143 }
@@ -225,6 +227,7 @@ public function delete(): bool
225227 LanguageRules::delete ($ this );
226228
227229 // apply before hook
230+ /** @var \Kirby\Cms\Language $language */
228231 $ language = $ kirby ->apply (
229232 'language.delete:before ' ,
230233 ['language ' => $ this ]
@@ -237,6 +240,9 @@ public function delete(): bool
237240 throw new Exception (message: 'The language could not be deleted ' );
238241 }
239242
243+ // delete custom translations file if defined
244+ $ language ->variables ()->delete ();
245+
240246 // if needed, convert content storage to single lang
241247 foreach ($ kirby ->models () as $ model ) {
242248 if ($ language ->isLast () === true ) {
@@ -483,7 +489,11 @@ public function rules(): array
483489 */
484490 public function save (): static
485491 {
486- $ existingData = Data::read ($ this ->root (), fail: false );
492+ try {
493+ $ existingData = Data::read ($ this ->root (), fail: false );
494+ } catch (Throwable ) {
495+ $ existingData = [];
496+ }
487497
488498 $ data = [
489499 ...$ existingData ,
@@ -492,12 +502,19 @@ public function save(): static
492502 'direction ' => $ this ->direction (),
493503 'locale ' => Locale::export ($ this ->locale ()),
494504 'name ' => $ this ->name (),
495- 'translations ' => $ this ->translations (),
505+ 'variables ' => $ this ->variables ()-> toArray (),
496506 'url ' => $ this ->url ,
497507 ];
498508
499509 ksort ($ data );
500510
511+ // save translations to the custom root and remove translations
512+ // to prevent duplication write into the language file
513+ if ($ this ->variables ()->root () !== null ) {
514+ $ this ->variables ()->save ($ data ['translations ' ] ?? []);
515+ $ data ['translations ' ] = [];
516+ }
517+
501518 Data::write ($ this ->root (), $ data );
502519
503520 return $ this ;
@@ -558,11 +575,14 @@ public function toArray(): array
558575 }
559576
560577 /**
561- * Returns the translation strings for this language
578+ * Alias for Language::variables()
579+ *
580+ * @deprecated 5.0.0 Use `::variables()` instead
581+ * @todo 7.0.0 Remove the method
562582 */
563- public function translations (): array
583+ public function translations (): LanguageVariables
564584 {
565- return $ this ->translations ;
585+ return $ this ->variables () ;
566586 }
567587
568588 /**
@@ -589,6 +609,7 @@ public function update(array|null $props = null): static
589609 $ props ['slug ' ] = Str::slug ($ props ['slug ' ] ?? null );
590610
591611 // trigger before hook
612+ /** @var \Kirby\Cms\Language $language */
592613 $ language = $ kirby ->apply (
593614 'language.update:before ' ,
594615 [
@@ -601,7 +622,7 @@ public function update(array|null $props = null): static
601622 $ language = $ language ->clone ($ props );
602623
603624 if (isset ($ props ['translations ' ]) === true ) {
604- $ language ->translations = $ props ['translations ' ];
625+ $ language ->variables = $ language -> variables -> update ( $ props ['translations ' ] ?? null ) ;
605626 }
606627
607628 // validate the language rules after before hook was applied
@@ -655,4 +676,12 @@ public function variable(
655676 key: $ key
656677 );
657678 }
679+
680+ /**
681+ * Returns the language variables object for this language
682+ */
683+ public function variables (): LanguageVariables
684+ {
685+ return $ this ->variables ;
686+ }
658687}
0 commit comments