From 7449cd6e594b256114fcdb58aa2b5fcdcc1edfe9 Mon Sep 17 00:00:00 2001 From: Alexis Gousseau Date: Thu, 15 Jun 2023 12:15:19 +0200 Subject: [PATCH] add translations --- app/Providers/TranslationServiceProvider.php | 77 ++++++++++++++++++++ config/app.php | 1 + resources/ts/modules/trans.ts | 49 +++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 app/Providers/TranslationServiceProvider.php create mode 100644 resources/ts/modules/trans.ts diff --git a/app/Providers/TranslationServiceProvider.php b/app/Providers/TranslationServiceProvider.php new file mode 100644 index 0000000..816aaa6 --- /dev/null +++ b/app/Providers/TranslationServiceProvider.php @@ -0,0 +1,77 @@ +collectLocalesStrings() as $locale) { + // * Suported locales + Cache::rememberForever(sprintf('translations.%s', $locale), function () use ($locale) { + $translations = [ + 'php' => $this->phpTranslations($locale), + 'json' => $this->jsonTranslations($locale), + ]; + return $translations; + }); + } + } + + /** + * Gather provided langs checking from files + * + * @return Collection + */ + private function collectLocalesStrings(): Collection + { + return collect(File::allFiles(resource_path('lang/')))->flatMap(function ($file) { + if ($file->getRelativePath()) { + return [$file->getRelativePath() => '']; + } + })->keys(); + } + + /** + * Gather all php translations + * + * @param string $locale + * @return array + */ + private function phpTranslations(string $locale): array + { + $path = resource_path("lang/$locale"); + + return collect(File::allFiles($path))->flatMap(function ($file) use ($locale) { + $translation = $file->getBasename('.php'); + return [$translation => trans($translation, [], $locale)]; + })->all(); + } + + /** + * Gather json translations + * + * @param string $locale + * @return array + */ + private function jsonTranslations(string $locale): array + { + $path = resource_path("lang/$locale.json"); + + if (is_string($path) && is_readable($path)) { + return json_decode(file_get_contents($path), true) ?? []; + } + + return []; + } +} diff --git a/config/app.php b/config/app.php index b7f891a..a3c9f20 100644 --- a/config/app.php +++ b/config/app.php @@ -175,6 +175,7 @@ return [ App\Providers\AuthServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, + App\Providers\TranslationServiceProvider::class, App\Providers\ViewServiceProvider::class, ], diff --git a/resources/ts/modules/trans.ts b/resources/ts/modules/trans.ts new file mode 100644 index 0000000..bd6b393 --- /dev/null +++ b/resources/ts/modules/trans.ts @@ -0,0 +1,49 @@ +export default { + data() { + return { + locale: window.__SYSTEM._locale, + }; + }, + methods: { + /** + * Translate the given key. + */ + __(key: string, replace: Record = {}): string { + let translation: string, + translationNotFound = true; + + try { + translation = key + .split(".") + .reduce( + (t, i) => t[i as any] ?? null, + window.__SYSTEM._translations.php + ) as string; + if (translation) { + translationNotFound = false; + } + } catch (e) { + translation = key; + } + + if (translationNotFound) { + translation = (window.__SYSTEM._translations.json[key as any] ?? + key) as string; + } + const vars = translation.match(/:[0-9A-Za-z_]+/g); + if (vars) { + for (const match of vars) { + try { + translation = translation.replace( + new RegExp(match, "g"), + replace[match.substring(1)] + ); + } catch (e) { + console.error("String replace failed ", e); + } + } + } + return translation; + }, + }, +};