From 70868f74520baf1b1cb764df9863c68c8cdf7e33 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 7 Nov 2026 17:44:23 +0000 Subject: [PATCH 1/2] Initial plan From d7b370ced4d070a109a27b885a14bdba0ce0a4aa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 7 Nov 2026 17:47:02 +0000 Subject: [PATCH 2/2] Support nested language translation files Co-authored-by: asika32764 <1639206+asika32764@users.noreply.github.com> --- packages/language/composer.json | 1 + packages/language/src/Language.php | 16 ++++++++++++-- packages/language/test/LanguageTest.php | 28 +++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/packages/language/composer.json b/packages/language/composer.json index f45c81aca..87222a868 100644 --- a/packages/language/composer.json +++ b/packages/language/composer.json @@ -21,6 +21,7 @@ "windwalker/test": "^4.0" }, "suggest": { + "symfony/yaml": "Required to load YAML language files." }, "minimum-stability": "beta", "autoload": { diff --git a/packages/language/src/Language.php b/packages/language/src/Language.php index 48581e531..c9350cf91 100644 --- a/packages/language/src/Language.php +++ b/packages/language/src/Language.php @@ -334,12 +334,24 @@ public function addString(string $key, string $string, ?string $locale = null): * @return $this */ public function addStrings(array $strings, ?string $locale = null): static + { + $this->addStringsRecursive($strings, $locale); + + return $this; + } + + private function addStringsRecursive(array $strings, ?string $locale, string $prefix = ''): void { foreach ($strings as $key => $string) { + $key = $prefix === '' ? (string) $key : $prefix . '.' . $key; + + if (is_array($string)) { + $this->addStringsRecursive($string, $locale, $key); + continue; + } + $this->addString($key, $string, $locale); } - - return $this; } /** diff --git a/packages/language/test/LanguageTest.php b/packages/language/test/LanguageTest.php index c2ae5f9b9..3bfc567e0 100644 --- a/packages/language/test/LanguageTest.php +++ b/packages/language/test/LanguageTest.php @@ -327,6 +327,34 @@ public function loadReadsStringsFromFileForGivenLocale(): void self::assertEquals('櫻花', $lang->trans('WINDWALKER_LANGUAGE_TEST_SAKURA')); } + #[Test] + public function loadFlattensNestedJsonAndPhpTranslations(): void + { + $json = new Language(); + $json->load(__DIR__ . '/fixtures/json/en-GB.json', 'json', 'en-GB'); + + $php = new Language(); + $php->load(__DIR__ . '/fixtures/php/en-GB.php', 'php', 'en-GB'); + + self::assertSame('Sakura', $json->trans('windwalker.language.test.sakura')); + self::assertSame('Olive', $json->trans('windwalker.language.test.olive')); + self::assertSame('Sakura', $php->trans('windwalker.language.test.sakura')); + } + + #[Test] + public function loadFlattensNestedYamlTranslationsWhenYamlIsAvailable(): void + { + if (!class_exists(\Symfony\Component\Yaml\Yaml::class)) { + self::markTestSkipped('Symfony YAML is not installed.'); + } + + $lang = new Language(); + $lang->load(__DIR__ . '/fixtures/yaml/en-GB.yml', 'yaml', 'en-GB'); + + self::assertSame('Sakura', $lang->trans('windwalker.language.test.sakura')); + self::assertSame('Olive', $lang->trans('windwalker.language.test.olive')); + } + #[Test] public function getSelectorReturnsSameLazyInstance(): void {