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.
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.
* 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.
* 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ů.
### 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-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
You can use this command to switch your project to latest preview version of the ABP framework packages.
@ -147,6 +170,7 @@ Usage:
````bash
abp switch-to-preview [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.

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.
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.
* 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.
* 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.
### 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). 你可以为自己的应用程序创建本地化用户界面.
除此之外,框架和预构建模块已经本地化了文本.请参阅[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/).
* 为本地化文本(json)文件(en.json文件同目录下)创建目标语言的新文件.
@ -49,6 +51,9 @@ ABP框架具有灵活的[本地化系统](../Localization.md). 你可以为自
* 翻译文本.
* 在Github上发送拉取请求(Pull request).
你还可以使用[ABP CLI](CLI.md)的`abp translation`命令来翻译本地化文本.
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-module"] = typeof(AddModuleCommand);
options.Commands["login"] = typeof(LoginCommand);
options.Commands["logout"] = typeof(LogoutCommand);
options.Commands["generate-proxy"] = typeof(GenerateProxyCommand);
options.Commands["logout"] = typeof(LogoutCommand);
options.Commands["generate-proxy"] = typeof(GenerateProxyCommand);
options.Commands["suite"] = typeof(SuiteCommand);
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.Events;
using System.IO;
@ -10,6 +11,8 @@ namespace Volo.Abp.Cli
{
private static void Main(string[] args)
{
Console.OutputEncoding = System.Text.Encoding.UTF8;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)

Loading…
Cancel
Save