Browse Source

Merge pull request #4088 from abpframework/maliming/abp-translate

Add cli translate command.
pull/4112/head
Halil İbrahim Kalkan 6 years ago
committed by GitHub
parent
commit
b705986197
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      docs/cs/Contribution/Index.md
  2. 40
      docs/cs/Contribution/Localization-Text-Files.md
  3. 24
      docs/en/CLI.md
  4. 6
      docs/en/Contribution/Index.md
  5. 31
      docs/en/Contribution/Localization-Text-Files.md
  6. 7
      docs/zh-Hans/Contribution/Index.md
  7. 31
      docs/zh-Hans/Contribution/Localization-Text-Files.md
  8. 7
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs
  9. 443
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/TranslateCommand.cs
  10. 5
      framework/src/Volo.Abp.Cli/Volo/Abp/Cli/Program.cs

6
docs/cs/Contribution/Index.md

@ -41,7 +41,9 @@ Nový jazyk je publikován jakmile jsou minimálně tyto překlady dokončeny.
ABP framework má flexibilní [lokalizační systém](../Localization.md). Můžete tak vytvořit lokalizované uživatelské prostředí pro svou vlastní aplikaci. ABP framework má flexibilní [lokalizační systém](../Localization.md). Můžete tak vytvořit lokalizované uživatelské prostředí pro svou vlastní aplikaci.
K tomu mají framework a vestavěné moduly již lokalizované texty. Například [lokalizační texty pro Volo.Abp.UI balík](https://github.com/abpframework/abp/blob/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json). Můžete vytvořit nový soubor ve [stejné složce](https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi) k přidání překladu. K tomu mají framework a vestavěné moduly již lokalizované texty. Například [lokalizační texty pro Volo.Abp.UI balík](https://github.com/abpframework/abp/blob/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json).
Můžete vytvořit nový soubor ve [stejné složce](https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi) k přidání překladu.
* Naklonujte [ABP repozitář](https://github.com/abpframework/abp/) z Githubu. * Naklonujte [ABP repozitář](https://github.com/abpframework/abp/) z Githubu.
* Vytvořte nový soubor pro cílový jazyk pro lokalizační text v (json) souboru (u souboru en.json). * Vytvořte nový soubor pro cílový jazyk pro lokalizační text v (json) souboru (u souboru en.json).
@ -49,6 +51,8 @@ K tomu mají framework a vestavěné moduly již lokalizované texty. Napříkla
* Přeložte texty. * Přeložte texty.
* Zašlete pull request na Githubu. * Zašlete pull request na Githubu.
K překladu lokalizovaných textů můžete také použít příkaz `abp translate` of [ABP CLI](CLI.md).
ABP je modulářní framework, proto je zde mnoho zdrojů lokalizačních textů, jeden pro každý modul. K najití všech .json souborů, vyhledejte po naklonování repozitáře soubory "en.json". Můžete se taky podívat na [tento seznam](Localization-Text-Files.md) souborů lokalizačních textů. ABP je modulářní framework, proto je zde mnoho zdrojů lokalizačních textů, jeden pro každý modul. K najití všech .json souborů, vyhledejte po naklonování repozitáře soubory "en.json". Můžete se taky podívat na [tento seznam](Localization-Text-Files.md) souborů lokalizačních textů.
### Příspevky do blogu a návody ### Příspevky do blogu a návody

40
docs/cs/Contribution/Localization-Text-Files.md

@ -1,40 +0,0 @@
## Textové soubory pro lokalizaci
Toto je seznam lokalizačních textových souborů pro každého kdo chce přispět k překladu textů ve frameworku. Tento seznam budeme udržovat aktuální:
* https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en.json
* https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/en.json
* https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/en.json
* https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/en.json
* https://github.com/abpframework/abp/tree/master/modules/account/src/Volo.Abp.Account.Web/Localization/Resources/AbpAccount/Web/en.json
* https://github.com/abpframework/abp/tree/master/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Localization/Resources/Blogging/ApplicationContracts/en.json
* https://github.com/abpframework/abp/tree/master/modules/blogging/src/Volo.Blogging.Web/Localization/Resources/Blogging/Web/en.json
* https://github.com/abpframework/abp/tree/master/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/en.json
* https://github.com/abpframework/abp/tree/master/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/en.json
* https://github.com/abpframework/abp/tree/master/modules/docs/src/Volo.Docs.Admin.Web/Localization/Resources/Docs/Web/en.json
* https://github.com/abpframework/abp/tree/master/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json
* https://github.com/abpframework/abp/tree/master/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/Localization/ApplicationContracts/en.json
* https://github.com/abpframework/abp/tree/master/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/Localization/Domain/en.json
* https://github.com/abpframework/abp/tree/master/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Localization/Resources/FeatureManagement/en.json
* https://github.com/abpframework/abp/tree/master/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Localization/ApplicationContracts/en.json
* https://github.com/abpframework/abp/tree/master/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Localization/Domain/en.json
* https://github.com/abpframework/abp/tree/master/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/en.json
* https://github.com/abpframework/abp/tree/master/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Localization/Resources/AbpPermissionManagement/en.json
* https://github.com/abpframework/abp/tree/master/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Localization/Resources/AbpSettingManagement/en.json
* https://github.com/abpframework/abp/tree/master/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/Localization/ApplicationContracts/en.json
* https://github.com/abpframework/abp/tree/master/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Localization/Resources/AbpTenantManagement/Web/en.json
* https://github.com/abpframework/abp-samples/tree/master/BookStore/src/Acme.BookStore.Domain.Shared/Localization/BookStore/en.json
* https://github.com/abpframework/abp-samples/tree/master/DashboardDemo/src/DashboardDemo.Domain/Localization/DashboardDemo/en.json
* https://github.com/abpframework/abp/tree/master/samples/MicroserviceDemo/modules/product/src/ProductManagement.Application.Contracts/ProductManagement/Localization/ApplicationContracts/en.json
* https://github.com/abpframework/abp/tree/master/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/en.json
* https://github.com/abpframework/abp/tree/master/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/Localization/Resources/ProductManagement/en.json
* https://github.com/abpframework/abp/tree/master/templates/mvc-module/src/MyCompanyName.MyProjectName.Application.Contracts/Localization/MyProjectName/ApplicationContracts/en.json
* https://github.com/abpframework/abp/tree/master/templates/mvc-module/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/DomainShared/en.json
* https://github.com/abpframework/abp/tree/master/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Localization/MyProjectName/Web/en.json
* https://github.com/abpframework/abp/tree/master/templates/mvc/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/en.json

24
docs/en/CLI.md

@ -138,6 +138,29 @@ abp update [options]
* `--solution-path` or `-sp`: Specify the solution path. Use the current directory by default * `--solution-path` or `-sp`: Specify the solution path. Use the current directory by default
* `--solution-name` or `-sn`: Specify the solution name. Search `*.sln` files in the directory by default. * `--solution-name` or `-sn`: Specify the solution name. Search `*.sln` files in the directory by default.
### translate
This command will create a unified json file based on the reference culture. It will search all localized `json` files in the current directory. It will include the localized translations that are missing from the reference culture. You can complete the translation in this `json`(eg: `abp-translation.json`) file.
Finally, use `abp translate --apply` to submit the changes.This command will synchronize your translated text to the localized `json` file in the project. You can view the changes of localized information through git.
Usage:
````bash
abp translate [options]
````
#### Options
* `--culture` or `-c`: Target culture. eg: `zh-Hans`
* `--reference-culture` or `-r`: Default `en`
* `--output` or `-o`: Output file name. Default `abp-translation.json`.
* `--all-values` or `-all`: Include all keys. Default `false`
* `--apply` or `-a`: Creates or updates the file for the translated culture.
* `--file` or `-f`: Default: `abp-translation.json`
### switch-to-preview ### switch-to-preview
You can use this command to switch your project to latest preview version of the ABP framework packages. You can use this command to switch your project to latest preview version of the ABP framework packages.
@ -147,6 +170,7 @@ Usage:
````bash ````bash
abp switch-to-preview [options] abp switch-to-preview [options]
```` ````
#### Options #### Options
`--solution-directory` or `-sd`: Specifies the directory. The solution should be in that directory or in any of its sub directories. If not specified, default is the current directory. `--solution-directory` or `-sd`: Specifies the directory. The solution should be in that directory or in any of its sub directories. If not specified, default is the current directory.

6
docs/en/Contribution/Index.md

@ -41,7 +41,9 @@ A new language is published after these minimum translations have been completed
ABP framework has a flexible [localization system](../Localization.md). You can create localized user interfaces for your own application. ABP framework has a flexible [localization system](../Localization.md). You can create localized user interfaces for your own application.
In addition to that, the framework and pre-build modules have already localized texts. As an example, see [the localization texts for the Volo.Abp.UI package](https://github.com/abpframework/abp/blob/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json). You can create a new file in the [same folder](https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi) to translate it. In addition to that, the framework and pre-build modules have already localized texts. As an example, see [the localization texts for the Volo.Abp.UI package](https://github.com/abpframework/abp/blob/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json).
You can create a new file in the [same folder](https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi) to translate it.
* Clone the [ABP repository](https://github.com/abpframework/abp/) from Github. * Clone the [ABP repository](https://github.com/abpframework/abp/) from Github.
* Create a new file for the target language for a localization text (json) file (near to the en.json file). * Create a new file for the target language for a localization text (json) file (near to the en.json file).
@ -49,6 +51,8 @@ In addition to that, the framework and pre-build modules have already localized
* Translate the texts. * Translate the texts.
* Send pull request on Github. * Send pull request on Github.
You can also use the `abp translate` command of [ABP CLI](CLI.md) to translate localized texts.
ABP is a modular framework. So there are many localization text resource, one per module. To find all .json files, you can search for "en.json" after cloning the repository. You can also check [this list](Localization-Text-Files.md) for a list of localization text files. ABP is a modular framework. So there are many localization text resource, one per module. To find all .json files, you can search for "en.json" after cloning the repository. You can also check [this list](Localization-Text-Files.md) for a list of localization text files.
### Blog Posts & Tutorials ### Blog Posts & Tutorials

31
docs/en/Contribution/Localization-Text-Files.md

@ -1,31 +0,0 @@
## Localization Text Files
Here, a list of localization text files for anyone wants to contribute to localization of the texts coming from the framework. We will keep this list up to date:
* https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en.json
* https://github.com/abpframework/abp/blob/master/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/en.json
* https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/en.json
* https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/en.json
* https://github.com/abpframework/abp/blob/master/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/en.json
* https://github.com/abpframework/abp/tree/master/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Localization/Resources/Blogging/ApplicationContracts/en.json
* https://github.com/abpframework/abp/tree/master/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/en.json
* https://github.com/abpframework/abp/tree/master/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/en.json
* https://github.com/abpframework/abp/tree/master/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/en.json
* https://github.com/abpframework/abp/tree/master/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json
* https://github.com/abpframework/abp/tree/master/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json
* https://github.com/abpframework/abp/tree/master/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json
* https://github.com/abpframework/abp/tree/master/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/en.json
* https://github.com/abpframework/abp/tree/master/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/en.json
* https://github.com/abpframework/abp/tree/master/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/en.json
* https://github.com/abpframework/abp-samples/tree/master/BookStore/src/Acme.BookStore.Domain.Shared/Localization/BookStore/en.json
* https://github.com/abpframework/abp-samples/tree/master/DashboardDemo/src/DashboardDemo.Domain.Shared/Localization/DashboardDemo/en.json
* https://github.com/abpframework/abp/tree/master/samples/MicroserviceDemo/modules/product/src/ProductManagement.Application.Contracts/ProductManagement/Localization/ApplicationContracts/en.json
* https://github.com/abpframework/abp/tree/master/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/en.json
* https://github.com/abpframework/abp/tree/master/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/Localization/Resources/ProductManagement/en.json
* https://github.com/abpframework/abp/tree/master/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/en.json

7
docs/zh-Hans/Contribution/Index.md

@ -41,7 +41,9 @@ ABP是[开源](https://github.com/abpframework)和社区驱动项目. 本指南
ABP框架具有灵活的[本地化系统](../Localization.md). 你可以为自己的应用程序创建本地化用户界面. ABP框架具有灵活的[本地化系统](../Localization.md). 你可以为自己的应用程序创建本地化用户界面.
除此之外,框架和预构建模块已经本地化了文本.请参阅[Volo.Abp.UI包的本地化文本](https://github.com/abpframework/abp/blob/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json).你可以在[相同文件夹](https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi)中创建一个新文件进行翻译. 除此之外,框架和预构建模块已经本地化了文本.请参阅[Volo.Abp.UI包的本地化文本](https://github.com/abpframework/abp/blob/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json).
你可以在[相同文件夹](https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi)中创建一个新文件进行翻译.
* 从Github克隆[ABP存储库](https://github.com/abpframework/abp/). * 从Github克隆[ABP存储库](https://github.com/abpframework/abp/).
* 为本地化文本(json)文件(en.json文件同目录下)创建目标语言的新文件. * 为本地化文本(json)文件(en.json文件同目录下)创建目标语言的新文件.
@ -49,6 +51,9 @@ ABP框架具有灵活的[本地化系统](../Localization.md). 你可以为自
* 翻译文本. * 翻译文本.
* 在Github上发送拉取请求(Pull request). * 在Github上发送拉取请求(Pull request).
你还可以使用[ABP CLI](CLI.md)的`abp translation`命令来翻译本地化文本.
ABP是一个模块化框架. 所以有很多本地化文本资源, 每个模块都有一个. 要查找所有.json文件,可以在克隆存储库后搜索"en.json". 你还可以检查[此列表](Localization-Text-Files.md)以获取本地化文本文件列表. ABP是一个模块化框架. 所以有很多本地化文本资源, 每个模块都有一个. 要查找所有.json文件,可以在克隆存储库后搜索"en.json". 你还可以检查[此列表](Localization-Text-Files.md)以获取本地化文本文件列表.
### 博客文章和教程 ### 博客文章和教程

31
docs/zh-Hans/Contribution/Localization-Text-Files.md

@ -1,31 +0,0 @@
## 本地化文本文件
这是一个来自框架的本地化文本文件列表, 任何人都可以做出贡献. 我们会将此列表保持最新:
* https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en.json
* https://github.com/abpframework/abp/blob/master/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/en.json
* https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/en.json
* https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/en.json
* https://github.com/abpframework/abp/tree/master/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/en.json
* https://github.com/abpframework/abp/blob/master/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/en.json
* https://github.com/abpframework/abp/tree/master/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Localization/Resources/Blogging/ApplicationContracts/en.json
* https://github.com/abpframework/abp/tree/master/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/en.json
* https://github.com/abpframework/abp/tree/master/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/en.json
* https://github.com/abpframework/abp/tree/master/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/en.json
* https://github.com/abpframework/abp/tree/master/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json
* https://github.com/abpframework/abp/tree/master/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json
* https://github.com/abpframework/abp/tree/master/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json
* https://github.com/abpframework/abp/tree/master/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/en.json
* https://github.com/abpframework/abp/tree/master/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/en.json
* https://github.com/abpframework/abp/tree/master/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/en.json
* https://github.com/abpframework/abp-samples/tree/master/BookStore/src/Acme.BookStore.Domain.Shared/Localization/BookStore/en.json
* https://github.com/abpframework/abp-samples/tree/master/DashboardDemo/src/DashboardDemo.Domain.Shared/Localization/DashboardDemo/en.json
* https://github.com/abpframework/abp/tree/master/samples/MicroserviceDemo/modules/product/src/ProductManagement.Application.Contracts/ProductManagement/Localization/ApplicationContracts/en.json
* https://github.com/abpframework/abp/tree/master/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/en.json
* https://github.com/abpframework/abp/tree/master/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/Localization/Resources/ProductManagement/en.json
* https://github.com/abpframework/abp/tree/master/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/en.json

7
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs

@ -28,11 +28,12 @@ namespace Volo.Abp.Cli
options.Commands["add-package"] = typeof(AddPackageCommand); options.Commands["add-package"] = typeof(AddPackageCommand);
options.Commands["add-module"] = typeof(AddModuleCommand); options.Commands["add-module"] = typeof(AddModuleCommand);
options.Commands["login"] = typeof(LoginCommand); options.Commands["login"] = typeof(LoginCommand);
options.Commands["logout"] = typeof(LogoutCommand); options.Commands["logout"] = typeof(LogoutCommand);
options.Commands["generate-proxy"] = typeof(GenerateProxyCommand); options.Commands["generate-proxy"] = typeof(GenerateProxyCommand);
options.Commands["suite"] = typeof(SuiteCommand); options.Commands["suite"] = typeof(SuiteCommand);
options.Commands["switch-to-preview"] = typeof(SwitchNightlyPreviewCommand); options.Commands["switch-to-preview"] = typeof(SwitchNightlyPreviewCommand);
options.Commands["switch-to-stable"] = typeof(SwitchStableCommand); options.Commands["switch-to-stable"] = typeof(SwitchStableCommand);
options.Commands["translate"] = typeof(TranslateCommand);
}); });
} }
} }

443
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/TranslateCommand.cs

@ -0,0 +1,443 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Volo.Abp.Cli.Args;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.Commands
{
public class TranslateCommand: IConsoleCommand, ITransientDependency
{
public ILogger<TranslateCommand> Logger { get; set; }
public Task ExecuteAsync(CommandLineArgs commandLineArgs)
{
var currentDirectory = Directory.GetCurrentDirectory();
var apply = commandLineArgs.Options.ContainsKey(Options.Apply.Short) || commandLineArgs.Options.ContainsKey(Options.Apply.Long);
if (apply)
{
var inputFile = Path.Combine(currentDirectory,
commandLineArgs.Options.GetOrNull(Options.File.Short, Options.File.Long)
?? "abp-translation.json");
Logger.LogInformation("Abp translate apply...");
Logger.LogInformation("Input file: " + inputFile);
ApplyAbpTranslateInfo(currentDirectory, inputFile);
}
else
{
var targetCulture = commandLineArgs.Options.GetOrNull(Options.Culture.Short, Options.Culture.Long);
if (targetCulture == null)
{
throw new CliUsageException(
"Target culture is missing!" +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
}
var referenceCulture = commandLineArgs.Options.GetOrNull(Options.ReferenceCulture.Short, Options.ReferenceCulture.Long)
?? "en";
var outputFile = Path.Combine(currentDirectory,
commandLineArgs.Options.GetOrNull(Options.Output.Short, Options.Output.Long)
?? "abp-translation.json");
var allValues = commandLineArgs.Options.ContainsKey(Options.AllValues.Short) ||
commandLineArgs.Options.ContainsKey(Options.AllValues.Long);
Logger.LogInformation("Abp translate...");
Logger.LogInformation("Target culture: " + targetCulture);
Logger.LogInformation("Reference culture: " + referenceCulture);
Logger.LogInformation("Output file: " + outputFile);
if (allValues)
{
Logger.LogInformation("Include all keys");
}
var translateInfo = GetAbpTranslateInfo(currentDirectory, targetCulture, referenceCulture, allValues);
File.WriteAllText(outputFile, JsonConvert.SerializeObject(translateInfo, Formatting.Indented));
Logger.LogInformation($"The translation file has been created.");
}
return Task.CompletedTask;
}
private AbpTranslateInfo GetAbpTranslateInfo(string directory, string targetCultureName, string referenceCultureName, bool allValues)
{
var translateInfo = new AbpTranslateInfo
{
ReferenceCulture = referenceCultureName,
TargetCulture = targetCultureName,
Resources = new List<AbpTranslateResource>()
};
var referenceCultureFiles = GetCultureJsonFiles(directory, referenceCultureName);
foreach (var filePath in referenceCultureFiles)
{
var directoryName = Path.GetDirectoryName(filePath) ?? string.Empty;
var referenceLocalizationInfo = GetAbpLocalizationInfoOrNull(filePath);
if (referenceLocalizationInfo == null) // Not abp json file
{
continue;
}
var resource = new AbpTranslateResource
{
ResourcePath = directoryName,
Texts = new List<AbpTranslateResourceText>()
};
foreach (var text in referenceLocalizationInfo.Texts)
{
resource.Texts.Add(new AbpTranslateResourceText
{
LocalizationKey = text.Name,
Reference = text.Value,
Target = string.Empty
});
}
//Use target json file content to fill resource texts
var targetFile = Path.Combine(directoryName, $"{targetCultureName}.json");
if (File.Exists(targetFile))
{
var targetLocalizationInfo = GetAbpLocalizationInfoOrNull(targetFile);
foreach (var referenceResourceText in resource.Texts)
{
var text = targetLocalizationInfo.Texts.FirstOrDefault(x => x.Name == referenceResourceText.LocalizationKey);
referenceResourceText.Target = text?.Value ?? string.Empty;
}
}
if (!allValues)
{
//Only include missing keys.
resource.Texts.RemoveAll(x => !x.Target.Equals(string.Empty));
}
if (resource.Texts.Any())
{
translateInfo.Resources.Add(resource);
}
}
return translateInfo;
}
private void ApplyAbpTranslateInfo(string directory, string filename)
{
var translateJsonPath = Path.Combine(directory, filename);
if (!File.Exists(translateJsonPath))
{
throw new CliUsageException(
$"{translateJsonPath} file does not exist.." +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
}
var translateInfo = GetAbpTranslateInfo(translateJsonPath);
foreach (var resource in translateInfo.Resources)
{
var targetFile = Path.Combine(resource.ResourcePath, translateInfo.TargetCulture + ".json");
var targetLocalizationInfo = File.Exists(targetFile)
? GetAbpLocalizationInfoOrNull(targetFile)
: new AbpLocalizationInfo()
{
Culture = translateInfo.TargetCulture,
Texts = new List<NameValue>()
};
if (targetLocalizationInfo == null)
{
throw new CliUsageException(
$"Failed to get localization information from {targetFile} file." +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
}
var referenceFile = Path.Combine(resource.ResourcePath, translateInfo.ReferenceCulture + ".json");
if (!File.Exists(referenceFile))
{
throw new CliUsageException(
$"{referenceFile} file does not exist.." +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
}
var referenceLocalizationInfo = GetAbpLocalizationInfoOrNull(referenceFile);
if (referenceLocalizationInfo == null)
{
throw new CliUsageException(
$"Failed to get localization information from {referenceFile} file." +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
}
foreach (var text in resource.Texts)
{
var targetText = targetLocalizationInfo.Texts.FirstOrDefault(x => x.Name == text.LocalizationKey);
if (targetText != null)
{
Logger.LogInformation($"Update translation: {targetText.Name} => " + text.Target);
targetText.Value = text.Target;
}
else
{
Logger.LogInformation($"Create translation: {text.LocalizationKey} => " + text.Target);
targetLocalizationInfo.Texts.Add(new NameValue(text.LocalizationKey, text.Target));
}
}
Logger.LogInformation($"Write translation json to {targetFile}.");
// sort keys
targetLocalizationInfo = SortLocalizedKeys(targetLocalizationInfo, referenceLocalizationInfo);
File.WriteAllText(targetFile, AbpLocalizationInfoToJsonFile(targetLocalizationInfo));
// remove translate json file(abp-translation.json)
File.Delete(translateJsonPath);
Logger.LogInformation($"Delete the {translateJsonPath} file, if you need to translate again, please re-run the [abp translate] command.");
}
}
private static IEnumerable<string> GetCultureJsonFiles(string path,string cultureName)
{
var excludeDirectory = new List<string>()
{
"node_modules",
Path.Combine("bin", "debug"),
Path.Combine("obj", "debug")
};
var allCultureInfos = CultureInfo.GetCultures(CultureTypes.AllCultures);
return Directory.GetFiles(path, "*.json", SearchOption.AllDirectories)
.Where(file => excludeDirectory.All(x => file.IndexOf(x, StringComparison.OrdinalIgnoreCase) == -1))
.Where(jsonFile => allCultureInfos.Any(culture => jsonFile.EndsWith($"{cultureName}.json", StringComparison.OrdinalIgnoreCase)));
}
private AbpLocalizationInfo GetAbpLocalizationInfoOrNull(string path)
{
if (!File.Exists(path))
{
throw new CliUsageException(
$"File {path} does not exist!" +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
}
var json = File.ReadAllText(path);
JObject jObject;
try
{
jObject = JObject.Parse(json);
}
catch (Exception e)
{
return null;
}
var culture = jObject.GetValue("culture");
var texts = jObject.GetValue("texts");
if (culture == null || texts == null)
{
return null;
}
var localizationInfo = new AbpLocalizationInfo
{
Culture = culture.Value<string>(),
Texts = new List<NameValue>()
};
foreach (var text in texts)
{
var property = (text as JProperty);
localizationInfo.Texts.Add(new NameValue(property?.Name, property?.Value.Value<string>()));
}
return localizationInfo;
}
private static string AbpLocalizationInfoToJsonFile(AbpLocalizationInfo localizationInfo)
{
var jObject = new JObject {{"culture", localizationInfo.Culture}};
var value = new JObject();
foreach (var text in localizationInfo.Texts)
{
value.Add(text.Name, text.Value);
}
jObject.Add("texts", value);
return jObject.ToString();
}
private AbpTranslateInfo GetAbpTranslateInfo(string path)
{
if (!File.Exists(path))
{
throw new CliUsageException(
$"File {path} does not exist!" +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
}
AbpTranslateInfo translateInfo;
try
{
translateInfo = JsonConvert.DeserializeObject<AbpTranslateInfo>(File.ReadAllText(path));
}
catch (Exception e)
{
throw new CliUsageException(
e.Message +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
}
return translateInfo;
}
private static AbpLocalizationInfo SortLocalizedKeys(AbpLocalizationInfo targetLocalizationInfo, AbpLocalizationInfo referenceLocalizationInfo)
{
var sortedLocalizationInfo = new AbpLocalizationInfo
{
Culture = targetLocalizationInfo.Culture,
Texts = new List<NameValue>()
};
foreach (var targetText in referenceLocalizationInfo.Texts.Select(text =>
targetLocalizationInfo.Texts.FirstOrDefault(x => x.Name == text.Name))
.Where(targetText => targetText != null))
{
sortedLocalizationInfo.Texts.Add(targetText);
}
return sortedLocalizationInfo;
}
public string GetUsageInfo()
{
var sb = new StringBuilder();
sb.AppendLine("");
sb.AppendLine("Usage:");
sb.AppendLine("");
sb.AppendLine(" abp translate [options]");
sb.AppendLine("");
sb.AppendLine("Options:");
sb.AppendLine("");
sb.AppendLine("--culture|-c <culture> Target culture. eg: zh-Hans");
sb.AppendLine("--reference-culture|-r <culture> Default: en");
sb.AppendLine("--output|-o <file-name> Output file name, Default abp-translation.json");
sb.AppendLine("--all-values|-all Include all keys. Default false");
sb.AppendLine("--apply|-a Creates or updates the file for the translated culture.");
sb.AppendLine("--file|-f <file-name> Default: abp-translation.json");
sb.AppendLine("");
sb.AppendLine("Examples:");
sb.AppendLine("");
sb.AppendLine(" abp translate -c zh-Hans");
sb.AppendLine(" abp translate -c zh-Hans -r en -a");
sb.AppendLine(" abp translate --apply");
sb.AppendLine(" abp translate -a -f my-translation.json");
sb.AppendLine("");
sb.AppendLine("See the documentation for more info: https://docs.abp.io/en/abp/latest/CLI");
return sb.ToString();
}
public string GetShortDescription()
{
return "Mainly used to translate ABP's resources (JSON files) easier.";
}
public static class Options
{
public static class Culture
{
public const string Short = "c";
public const string Long = "culture";
}
public static class ReferenceCulture
{
public const string Short = "r";
public const string Long = "reference-culture";
}
public static class Output
{
public const string Short = "o";
public const string Long = "output";
}
public static class AllValues
{
public const string Short = "all";
public const string Long = "all-values";
}
public static class Apply
{
public const string Short = "a";
public const string Long = "apply";
}
public static class File
{
public const string Short = "f";
public const string Long = "file";
}
}
public class AbpTranslateInfo
{
public string ReferenceCulture { get; set; }
public string TargetCulture { get; set; }
public List<AbpTranslateResource> Resources { get; set; }
}
public class AbpTranslateResource
{
public string ResourcePath { get; set; }
public List<AbpTranslateResourceText> Texts { get; set; }
}
public class AbpTranslateResourceText
{
public string LocalizationKey { get; set; }
public string Reference { get; set; }
public string Target { get; set; }
}
public class AbpLocalizationInfo
{
public string Culture { get; set; }
public List<NameValue> Texts { get; set; }
}
}
}

5
framework/src/Volo.Abp.Cli/Volo/Abp/Cli/Program.cs

@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection; using System;
using Microsoft.Extensions.DependencyInjection;
using Serilog; using Serilog;
using Serilog.Events; using Serilog.Events;
using System.IO; using System.IO;
@ -10,6 +11,8 @@ namespace Volo.Abp.Cli
{ {
private static void Main(string[] args) private static void Main(string[] args)
{ {
Console.OutputEncoding = System.Text.Encoding.UTF8;
Log.Logger = new LoggerConfiguration() Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information() .MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning) .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)

Loading…
Cancel
Save