UNPKG

@nativescript-community/l

Version:

Native internationalization plugin for NativeScript using native capabilities of each platform

247 lines (199 loc) 7.27 kB
# @nativescript-community/l [![npm](https://img.shields.io/npm/v/@nativescript-community/l.svg)](https://www.npmjs.com/package/@nativescript-community/l) [![npm](https://img.shields.io/npm/dm/@nativescript-community/l.svg)](https://www.npmjs.com/package/@nativescript-community/l) This is a plugin for NativeScript that implements internationalization (i18n) using the native capabilities of each platform. It is a direct fork of [nativescript-localize](https://github.com/EddyVerbruggen/nativescript-localize). ## Differences This plugin was created to have a different behavior from [nativescript-localize](https://github.com/EddyVerbruggen/nativescript-localize): * the default `localize` method was renamed to `l` * the default `l` method tries to load from a local JSON object * you can load such a JSON object with `loadLocalJSON` passing either the JSON or the path to it * if no local JSON, `l` load natively * keys are not encoded anymore, meaning keys are the same in native/js worlds. * the locale JSON must now be a trully nested object (no `.` in keys names) * special characters support has been dropped in keys names. ## Credits A lot of thanks goes out to [Eddy Verbruggen](https://github.com/EddyVerbruggen) and [Ludovic Fabrèges (@lfabreges)](https://github.com/lfabreges) for developing and maintaining [nativescript-localize](https://github.com/EddyVerbruggen/nativescript-localize). ## Table of contents * [Installation](#installation) * [Usage](#usage) * [Angular](#angular) * [Javascript](#javascript) * [Vue](#vue) * [File format](#file-format) * [Frequently asked questions](#frequently-asked-questions) * [How to set the default language?](#how-to-set-the-default-language) * [How to localize the application name?](#how-to-localize-the-application-name) * [How to localize iOS properties?](#how-to-localize-ios-properties) * [How to change the language dynamically at runtime?](#how-to-change-the-language-dynamically-at-runtime) * [Troubleshooting](#troubleshooting) * [The angular localization pipe does not work when in a modal context](#the-angular-localization-pipe-does-not-work-when-in-a-modal-context) ## Installation ```shell tns plugin add @nativescript-community/l ``` ## Usage Create a folder `i18n` in the `app` folder with the following structure: ``` app | i18n | en.json <-- english language | fr.default.json <-- french language (default)     | es.js ``` You need to [set the default langage](#how-to-set-the-default-language) and make sure it contains the [application name](#how-to-localize-the-application-name) to avoid any error. ### Angular #### app.module.ts ```ts import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core"; import { NativeScriptLocalizeModule } from "@nativescript-community/l/angular"; import { NativeScriptModule } from "nativescript-angular/nativescript.module"; import { AppComponent } from "./app.component"; @NgModule({ declarations: [AppComponent], bootstrap: [AppComponent], imports: [ NativeScriptModule, NativeScriptLocalizeModule ], schemas: [NO_ERRORS_SCHEMA] }) export class AppModule { } ``` #### Template ```xml <Label text="{{ 'Hello world !' | L }}"/> <Label text="{{ 'I am %s' | L:'user name' }}"/> ``` #### Script ```ts import { localize } from "@nativescript-community/l"; console.log(localize("Hello world !")); ``` ### Javascript / XML #### app.js ```js const application = require("application"); const localize = require("@nativescript-community/l"); application.setResources({ L: localize.l }); ``` #### Template ```xml <Label text="{{ L('Hello world !') }}"/> <Label text="{{ L('I am %s', 'user name') }}"/> ``` #### Script ```js const localize = require("@nativescript-community/l"); console.log(localize("Hello world !")); ``` #### Quirks ⚠️ If you notice translations work on your main XML page, but don't work on a page you navigate to, then add this little hack to the 'page loaded' function of that new page: ```js const page = args.object; page.bindingContext = new Observable(); ```` ### Vue #### app.js ```js import { l } from "@nativescript-community/l"; Vue.filter("L", l); ``` #### Template ```html <Label :text="'Hello world !'|L"></Label> <Label :text="'I am %s'|L('user name')"></Label> ``` ## File format Each file is imported using `require`, use the file format of your choice: #### JSON ```json { "app.name": "My app", "ios.info.plist": { "NSLocationWhenInUseUsageDescription": "This will be added to InfoPlist.strings" }, "user": { "name": "user.name", "email": "user.email" }, "array": [ "split the translation into ", "multiples lines" ], "sprintf": "format me %s", "sprintf with numbered placeholders": "format me %2$s one more time %1$s" } ``` #### Javascript ```js const i18n = { "app.name": "My app" }; module.exports = i18n; ``` ## Frequently asked questions ### How to set the default language? Add the `.default` extension to the default language file to set it as the fallback language: ``` fr.default.json ``` ### How to localize the application name? The `app.name` key is used to localize the application name: ```json { "app.name": "My app" } ``` ### How to localize iOS properties? Keys starting with `ios.info.plist.` are used to localize iOS properties: ```json { "ios.info.plist.NSLocationWhenInUseUsageDescription": "This will be added to InfoPlist.strings" } ``` ### How to change the language dynamically at runtime? Seeing this module now uses JSON objects. Overriding consist of 3 steps: * overriding native language, done with `overrideLocaleNative` * overriding json language, done with `loadLocalJSON` * updating all labels, buttons.... your job! ```typescript import { overrideLocaleNative } from "@nativescript-community/l/localize"; const localeOverriddenSuccessfully = overrideLocaleNative("en-GB"); // or "nl-NL", etc (or even just the part before the hyphen) ``` > **Important:** In case you are using [Android app bundle](https://docs.nativescript.org/tooling/publishing/android-app-bundle) to release your android app, add this to > App_Resources/Android/app.gradle to make sure all lanugages are bundled in the split apks ```groovy android { // there maybe other code here // bundle { language { enableSplit = false } } } ``` > **Tip:** you can get the default language on user's phone by using this ```ts import { device } from '@nativescript/core/platform'; console.log("user's language is", device.language.split('-')[0]); ``` > **Tip:** overrideLocaleNative method stores the language in a special key in app-settings, > you can access it like this, ```ts import { getString } from '@nativescript/core/application-settings'; console.log(getString('__app__language__')); // only available after the first time you use overrideLocaleNative(langName); ``` ## Troubleshooting ### The angular localization pipe does not work when in a modal context As a workaround, you can trigger a change detection from within your component constructor: ```ts constructor( private readonly params: ModalDialogParams, private readonly changeDetectorRef: ChangeDetectorRef, ) { setTimeout(() => this.changeDetectorRef.detectChanges(), 0); } ```