nativescript-i18n-tns2
使用本地标准的 i18n Nativescript 插件
npm i --save nativescript-i18n-tns2

nativescript-i18n-tns2

重要

这是对 nativescript-i18n 包的分支。这个分支旨在继续支持 3.0 版本之前的 Nativescript 版本,该版本引入了破坏性更改。

所有荣誉都归原作者 @rborn


这是一个用于 Nativescript 的插件,以简单的方式实现 i18n

它使用每个平台的原生功能,无需单独的 JS 或 JSON 文件。

它深受 NativeLang这个线程 的启发

该插件在应用程序级别定义了一个 L() 方法,因此它可以从 XML 和 JS 文件中访问。

! 请务必阅读 重要部分 ! :smile

致谢

感谢 @TheBrousse@ValioStoychev 在 iOS 方面的帮助以及 @alejonext 为创建初始模块所做的工作。

还要感谢所有使此存储库变得更好的 贡献者 :)

使用方法

将插件安装到您的应用程序中

npm install --save nativescript-i18n

app 文件夹中创建一个名为 i18n 的文件夹,其结构如下

App_Resources
i18n
|
|-- en
| |- strings.xml
|
|-- es
|- strings.xml

尽早在 app.js 中引入 nativescript-i18nglobals (我甚至在引入 application 模块之前这样做,前两行)。

	require('globals');
require('nativescript-i18n');

然后在代码中使用它,如下所示

XML 文件

简单字符串

	<Label text="{{ L('hello') }}">

它支持直接或从模型进行一个或多个替换

	<Label text="{{ L('hello') }}" class="title" textWrap="true" />
<Label text="{{ L('hello_replace','my friend') }}" class="message" textWrap="true" />
<Label text title="{{ L('multi_replace','direct replacement', modelReplacement) }}">

假设您在 strings.xml 中定义了定义,并在模型中定义了替换 modelReplacement 变量

	<string name="hello">Hello!</string>
<string formatted="false" name="hello_replace">Hello %s!</string>
<string formatted="false" name="multi_replace">We can replace directly in xml: %s or from the model: %s</string>

要为 i18n 文件定义自定义路径(除了 App_Resources/i18n),将以下配置添加到项目的 package.json 中

"nativescript-i18n": {
"customLangPath": "app/resources/i18n"
}

如果手机的语言与您定义的语言不匹配,则语言默认为英语。如果您想设置自己的默认语言,将此配置添加到项目的 package.json 中

请注意,在 iOS 上,设备选择的语言将基于 设置 -> 语言与区域 -> 首选语言顺序 中的顺序

"nativescript-i18n": {
"defaultLang": "es"
}

重要 !!

  • 对于所有具有替换的字符串定义,您需要添加 formatted=false

  • 引号和撇号需要转义 <string name="with_quotes">引号:\' 和引号:\"</string>

  • 为了使应用程序正确编译,我们需要在 strings.xml 中添加以下两行,这 还使 iOS 和 Android 上的应用程序名称本地化,并设置 Android 上初始活动的标题

    <string name="app_name">demo</string>
    <string name="title_activity_kimera">demo</string>
  • 有时您可能需要完全从设备/模拟器中删除应用程序,才能使插件完全工作(通常只在插件在项目开发的较晚阶段安装时发生)

  • 如果你在使用 TypeScript 时遇到 L 未定义的问题,请在你的 references.d.ts 文件中添加以下代码:/// <reference path="./node_modules/nativescript-i18n/references.d.ts" /> Nativescript i18n

JS 文件

	console.log(L('home'));
console.log(L('multi_replace', 'ONE', 'TWO'));

Angular

如果你在应用中使用 Angular,事情会稍微复杂一些。

我的 Angular 技能为零,但 @alejonext 在这个 评论 中有关于此问题的解决方案。

更新 28.06.2016

@AirMike@loloof64 通过测试和进一步改进 @alejonext 的 PR 做了很好的工作,因此插件现在包括对 Angular 的支持 :bow

在以常规方式将插件导入应用后,只需在你的文件(main.ts)中导入来自 nativescript-i18n/angular 的模块 NativeScriptI18nModule 即可

(请注意,以下说明是 TypeScript 而不是纯 JavaScript)

	import { NativeScriptI18nModule } from "nativescript-i18n/angular";

然后在你的应用模块中导入它

	@NgModule({


imports: [
NativeScriptI18nModule
]


})
export class AppModule { }

Angular 的用法是 {{ value | L:args }}

	<Button text="{{ 'Login' | L }}"></Button>

关于更详细的示例

你可以在 main.ts 中放置如下代码

    import { NativeScriptI18nModule } from 'nativescript-i18n/angular';

import { NativeScriptModule } from "nativescript-angular/platform";
import { NgModule } from "@angular/core";
import { AppComponent } from "./app.component";


@NgModule({

imports: [
NativeScriptModule,
NativeScriptI18nModule
],

declarations: [
AppComponent,
],
bootstrap: [AppComponent]
})
export class AppModule { }

对于主组件,假设以下 HTML 模板被使用(字符串定义将在下面提供)

    <GridLayout rows="*,*,*">
<label row="0" text="{{'menuitem_new_file' | L }}"></label>
<label row="1" text="{{'menuitem_new_folder' | L }}"></label>
<label row="2" text="{{'menuitem_new' | L:'---':'***':124.25693 }}"></label>
</GridLayout>

假设这是 "en" 的字符串定义(放置在 app/i18n/en/strings.xml 中)

    <resources>
<string name="app_name">Chess Exercices Cupboard</string>
<string name="title_activity_kimera">Chess Exercices Cupboard</string>

<string formatted="false" name="menuitem_new">%s New... %s %0.2f</string>
<string name="menuitem_new_file">File</string>
<string name="menuitem_new_folder">Folder</string>
</resources>

以及法语翻译(放置在 app/i18n/fr/srings.xml 中)

    <resources>
<string name="app_name">Chess Exercices Cupboard</string>
<string name="title_activity_kimera">Chess Exercices Cupboard</string>

<string formatted="false" name="menuitem_new">%s Nouveau... %s %0.2f</string>
<string name="menuitem_new_file">Fichier</string>
<string name="menuitem_new_folder">Dossier</string>
</resources>

如果你的手机配置为法语,你会看到如下内容

    Fichier
Dossier
--- Nouveau... *** 124.25693

或者,如果配置为英语或“未识别”语言

    File
Folder
--- New... *** 124.25693

演示

请查看 demo 文件夹中的示例。

iOS 权限文本

将以下特殊键添加到 app/i18n/(lang)/strings.xml 中,用于在显示权限警报时通知用户,以配置的语言显示。

键的描述
NSAppleMusicUsageDescription 指定你的应用使用媒体库的原因
NSBluetoothPeripheralUsageDescription 指定你的应用使用蓝牙的原因
NSCalendarsUsageDescription 指定你的应用访问用户日历的原因
NSCameraUsageDescription 指定你的应用访问设备相机的原因
NSContactsUsageDescription 指定你的应用访问用户联系人的原因
NSHealthShareUsageDescription 指定你的应用读取用户健康数据的原因
NSHealthUpdateUsageDescription 指定你的应用对用户健康数据进行更改的原因
NSHomeKitUsageDescription 指定你的应用访问用户 HomeKit 配置数据的原因
NSLocationAlwaysUsageDescription 指定你的应用在任何时候访问用户位置信息的原因
NSLocationWhenInUseUsageDescription 指定你的应用在使用时访问用户位置信息的原因
NSMicrophoneUsageDescription 指定你的应用访问设备麦克风的原因
NSMotionUsageDescription 指定你的应用访问设备加速度计的原因
NSPhotoLibraryUsageDescription 指定你的应用访问用户相册的原因
NSRemindersUsageDescription 指定你的应用访问用户提醒的原因
NSSiriUsageDescription 指定你的应用向 Siri 发送用户数据的原因
NSSpeechRecognitionUsageDescription 指定你的应用向苹果的语音识别服务器发送用户数据的原因

(伪) 路线图/想法

以下想法受到 此评论 以及本插件用户的帖子启发

  • [x] Android 实现 - 使用 App_Resources/Android/values/ 中的原生 strings.xml
  • [x] iOS实现 - 使用本地的Localizable.strings文件(这些文件需要放在哪里?)
  • [x] 允许格式化字符串,例如:L('hello', 'world')来翻译定义hello %s(以及/或其他类型%d等)
  • [ ] 可能需要一个命令行工具/命令来从我们的语言功能中提取字符串并将它们放入我们的strings.xml中进行翻译
  • [x] 将app/i18n中的strings.xml文件移动(具体的文件夹结构待定)并作为后续步骤的基准
    • [x] 在为Android编译前构建一个钩子来移动文件到正确的位置
    • [x] 在为iOS编译前构建一个钩子来翻译并移动文件到正确的位置
  • [ ] 资产(图片/启动画面等)怎么办?可能不在本插件的范围内
  • [x] 应用程序名称怎么办?
  • [ ] 我们是否需要一个模块级的缓存,这样我们就不必每次都跨越原生桥?(应该进行基准测试以决定这一点)
  • [x] 让缓存了解当前语言和语言更改
  • [x] Angular支持
  • [x] 语言文件的自定义路径(《https://github.com/rborn/nativescript-i18n/issues/28》#28)
  • [x] 设置应用程序的默认语言(《https://github.com/rborn/nativescript-i18n/issues/11》#11)
  • [x] 在iOS上显示应用程序权限警告的翻译(《https://github.com/rborn/nativescript-i18n/issues/45》#45)
  • [ ] 如果某些文件无法创建,报告错误