diff --git a/app/Listeners/GeneratePluginTranslations.php b/app/Listeners/GeneratePluginTranslations.php
new file mode 100644
index 00000000..a0a714f9
--- /dev/null
+++ b/app/Listeners/GeneratePluginTranslations.php
@@ -0,0 +1,46 @@
+filesystem = $filesystem;
+ $this->plugins = $plugins;
+ }
+
+ public function handle()
+ {
+ $plugins = $this->plugins->getEnabledPlugins();
+ $locales = array_keys(config('locales'));
+
+ array_walk($locales, function ($locale) use ($plugins) {
+ $i18n = $plugins
+ ->filter(function (Plugin $plugin) use ($locale) {
+ return $this->filesystem->exists(
+ $plugin->getPath()."/lang/$locale/front-end.yml"
+ );
+ })
+ ->map(function (Plugin $plugin) use ($locale) {
+ return trans($plugin->namespace.'::front-end');
+ });
+
+ if ($i18n->isNotEmpty()) {
+ $content = 'Object.assign(blessing.i18n, '.
+ $i18n->toJson(JSON_UNESCAPED_UNICODE).')';
+ $this->filesystem->put(public_path("lang/${locale}_plugin.js"), $content);
+ }
+ });
+ }
+}
diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php
index ab4b4dca..145e1ab8 100644
--- a/app/Providers/EventServiceProvider.php
+++ b/app/Providers/EventServiceProvider.php
@@ -23,9 +23,11 @@ class EventServiceProvider extends ServiceProvider
],
'App\Events\PluginWasEnabled' => [
'App\Listeners\CopyPluginAssets',
+ 'App\Listeners\GeneratePluginTranslations',
],
'App\Events\PluginVersionChanged' => [
'App\Listeners\CopyPluginAssets',
+ 'App\Listeners\GeneratePluginTranslations',
],
'App\Events\PluginBootFailed' => [
'App\Listeners\NotifyFailedPlugin',
diff --git a/app/Services/Translations/JavaScript.php b/app/Services/Translations/JavaScript.php
index ea8c9dc5..28be4f24 100644
--- a/app/Services/Translations/JavaScript.php
+++ b/app/Services/Translations/JavaScript.php
@@ -38,4 +38,14 @@ class JavaScript
return url("lang/$locale.js?t=$compiledModified");
}
+
+ public function plugin(string $locale): string
+ {
+ $path = public_path("lang/${locale}_plugin.js");
+ if ($this->filesystem->exists($path)) {
+ return url("lang/${locale}_plugin.js?t=".$this->filesystem->lastModified($path));
+ }
+
+ return '';
+ }
}
diff --git a/app/Services/Translations/Loader.php b/app/Services/Translations/Loader.php
index 723bb118..0b6ddb45 100644
--- a/app/Services/Translations/Loader.php
+++ b/app/Services/Translations/Loader.php
@@ -13,7 +13,7 @@ class Loader extends TranslationLoaderManager
$full = "{$path}/{$locale}/{$group}.yml";
return count($translations) === 0 && $this->files->exists($full)
- ? resolve(Yaml::class)->loadYaml($full)
+ ? resolve(Yaml::class)->parse($full)
: [];
}
}
diff --git a/app/Services/Translations/Yaml.php b/app/Services/Translations/Yaml.php
index 7648b410..bc6cc9d4 100644
--- a/app/Services/Translations/Yaml.php
+++ b/app/Services/Translations/Yaml.php
@@ -15,7 +15,7 @@ class Yaml
$this->cache = $cache;
}
- public function loadYaml(string $path): array
+ public function parse(string $path): array
{
$key = 'yaml-trans-'.md5($path).'-'.filemtime($path);
diff --git a/resources/misc/changelogs/en/5.0.0.md b/resources/misc/changelogs/en/5.0.0.md
index a52fb783..49713043 100644
--- a/resources/misc/changelogs/en/5.0.0.md
+++ b/resources/misc/changelogs/en/5.0.0.md
@@ -15,6 +15,7 @@
- Refactor account system.
- PHP version requirement is increased to 7.2.0.
- Use `install.lock` file to detect status of installation.
+- Load front end i18n text from `lang/front-end.yml` of a plugin automatically.
## Fixed
diff --git a/resources/misc/changelogs/zh_CN/5.0.0.md b/resources/misc/changelogs/zh_CN/5.0.0.md
index 773dbccf..5a46d77f 100644
--- a/resources/misc/changelogs/zh_CN/5.0.0.md
+++ b/resources/misc/changelogs/zh_CN/5.0.0.md
@@ -15,6 +15,7 @@
- 重构用户系统
- PHP 版本最低要求为 7.2.0
- 使用 `install.lock` 文件来检测安装状态
+- 插件系统:自动从 `lang/front-end.yml` 中加载前端多语言
## 修复
diff --git a/resources/views/common/dependencies/script.blade.php b/resources/views/common/dependencies/script.blade.php
index 55005e6a..3c62af84 100644
--- a/resources/views/common/dependencies/script.blade.php
+++ b/resources/views/common/dependencies/script.blade.php
@@ -1,5 +1,6 @@
@inject('intl', 'App\Services\Translations\JavaScript')
+
{{-- Content added by plugins dynamically --}}
diff --git a/tests/ListenersTest/GeneratePluginTranslationsTest.php b/tests/ListenersTest/GeneratePluginTranslationsTest.php
new file mode 100644
index 00000000..980a2b6e
--- /dev/null
+++ b/tests/ListenersTest/GeneratePluginTranslationsTest.php
@@ -0,0 +1,40 @@
+ ['en' => [], 'jp' => []]]);
+ $this->mock(PluginManager::class, function ($mock) {
+ $mock->shouldReceive('getEnabledPlugins')
+ ->with()
+ ->once()
+ ->andReturn(collect([new Plugin('/reina', ['namespace' => 'れいな'])]));
+ });
+ $this->mock(Filesystem::class, function ($mock) {
+ $mock->shouldReceive('exists')
+ ->with('/reina/lang/en/front-end.yml')
+ ->once()
+ ->andReturn(false);
+ $mock->shouldReceive('exists')
+ ->with('/reina/lang/jp/front-end.yml')
+ ->once()
+ ->andReturn(true);
+ $mock->shouldReceive('put')
+ ->with(
+ public_path('lang/jp_plugin.js'),
+ 'Object.assign(blessing.i18n, ["れいな::front-end"])'
+ )
+ ->once();
+ });
+
+ $this->app->call('App\Listeners\GeneratePluginTranslations@handle');
+ }
+}
diff --git a/tests/ServicesTest/TranslationsTest/JavaScriptTest.php b/tests/ServicesTest/TranslationsTest/JavaScriptTest.php
index 5267169c..e9598640 100644
--- a/tests/ServicesTest/TranslationsTest/JavaScriptTest.php
+++ b/tests/ServicesTest/TranslationsTest/JavaScriptTest.php
@@ -65,4 +65,25 @@ class JavaScriptTest extends TestCase
$this->assertEquals(url('lang/en.js?t=1'), resolve(JavaScript::class)->generate('en'));
}
+
+ public function testPlugin()
+ {
+ $this->mock(Filesystem::class, function ($mock) {
+ $mock->shouldReceive('exists')
+ ->with(public_path('lang/en_plugin.js'))
+ ->twice()
+ ->andReturn(false, true);
+ $mock->shouldReceive('lastModified')
+ ->with(public_path('lang/en_plugin.js'))
+ ->once()
+ ->andReturn(1);
+ });
+
+ $this->assertEquals('', resolve(JavaScript::class)->plugin('en'));
+
+ $this->assertEquals(
+ url('lang/en_plugin.js?t=1'),
+ resolve(JavaScript::class)->plugin('en')
+ );
+ }
}