nativeScript-ssi-i18n
使用原生标准的 i18n Nativescript 插件
npm i --save nativescript-ssi-i18n

nativeScript-i18n

这是一个实现 i18n 的 Nativescript 插件,简单易用。

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

它受到了 NativeLang这个线程 的启发。

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

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

致谢

最要感谢的是 Dan Tamas (@rborn) 在过去开发和维护这个插件。当他由于优先级转移而不得不放弃它时,他非常慷慨地将仓库 转移到我这里

感谢 @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');

如果您使用 TypeScript 并且想在代码中使用 L(),您需要在打算使用 L() 的文件中将 global 变量转换为 any,如下所示。您可以在 https://github.com/rborn/nativescript-i18n/issues/57 中了解更多信息。

	declare var global:any;

在代码中使用它如下

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>

  • 百分号需要通过设置 formatted="false" 并然后 重复它们 来转义: <string formatted="false" name="percent">百分号:%%</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编写的,而不是纯js)

	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实现 - 使用原生的strings.xml文件,位于App_Resources/Android/values/
  • [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] 自定义语言文件的路径(#28
  • [x] 设置应用程序的默认语言(#11
  • [x] 在iOS上显示应用程序权限警告的翻译(#45
  • [ ] 如果某些文件无法创建,报告错误
  • [ ] Webpack支持(#49#42