- 版本:0.1.8
- GitHub:
- NPM: https://npmjs.net.cn/package/nativescript-i18n-tns2
- 下载
- 昨日:0
- 上周:0
- 上月:0
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-i18n
和 globals
(我甚至在引入 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)
- [ ] 如果某些文件无法创建,报告错误