From 9f5bf52dc6ebdaab0fadcdeccdb8f482131f68a4 Mon Sep 17 00:00:00 2001 From: "francois.grand" <francois.grand@irstea.fr> Date: Tue, 25 Jul 2017 09:53:08 +0200 Subject: [PATCH] =?UTF-8?q?d=C3=A9but=20de=20prise=20en=20charge=20de=20l'?= =?UTF-8?q?internationalisation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 +++ package.json | 59 ++++++++++--------- src/app/i18n-providers.ts | 34 +++++++++++ .../param-input/param-input.component.html | 8 ++- src/app/param-input/param-input.component.ts | 26 ++++++-- src/index.html | 12 ++++ src/locale/messages.en.xlf | 10 ++++ src/main.ts | 7 ++- src/systemjs-text-plugin.js | 20 +++++++ 9 files changed, 149 insertions(+), 36 deletions(-) create mode 100644 src/app/i18n-providers.ts create mode 100644 src/locale/messages.en.xlf create mode 100644 src/systemjs-text-plugin.js diff --git a/README.md b/README.md index dbf6b6701..8f60da8dd 100644 --- a/README.md +++ b/README.md @@ -36,3 +36,12 @@ and then : ### To flag suspicious language usage `npm run lint` + +### To generate translation file + +`npm run i18n` + +This creates a _src/messages.xlf_ file. Move it to _src/locale/messages.<locale>.xlf_ + + +!!!! comment fait on pour mettre à jour un fichier messages.<locale>.xlf_ existant ? !!!! diff --git a/package.json b/package.json index 825abcde4..b2d55b18d 100644 --- a/package.json +++ b/package.json @@ -18,44 +18,47 @@ "test": "concurrently \"npm run build:watch\" \"karma start karma.conf.js\"", "pretest:once": "npm run build", "test:once": "karma start karma.conf.js --single-run", - "lint": "tslint ./src/**/*.ts -t verbose" + "lint": "tslint ./src/**/*.ts -t verbose", + "i18n": "ng-xi18n --i18nFormat=xlf -p src/tsconfig.json" }, "keywords": [], "author": "", "license": "MIT", "dependencies": { - "@angular/animations": "^4.2.5", - "@angular/common": "^4.2.5", - "@angular/compiler": "^4.2.5", - "@angular/core": "^4.2.5", - "@angular/forms": "^4.2.5", - "@angular/http": "^4.2.5", - "@angular/material": "^2.0.0-beta.7", - "@angular/platform-browser": "^4.2.5", - "@angular/platform-browser-dynamic": "^4.2.5", - "@angular/router": "^4.2.5", + "@angular/animations": "4.2.5", + "@angular/common": "4.2.5", + "@angular/compiler": "4.2.5", + "@angular/compiler-cli": "4.2.5", + "@angular/core": "4.2.5", + "@angular/forms": "4.2.5", + "@angular/http": "4.2.5", + "@angular/material": "2.0.0-beta.7", + "@angular/platform-browser": "4.2.5", + "@angular/platform-browser-dynamic": "4.2.5", + "@angular/router": "4.2.5", + "@angular/platform-server": "4.2.5", "systemjs": "0.19.40", - "core-js": "^2.4.1", + "core-js": "2.4.1", "rxjs": "5.0.1", - "zone.js": "^0.8.4", - "jalhyd": "^1.0.0" + "zone.js": "0.8.4", + "jalhyd": "1.0.0" }, "devDependencies": { - "concurrently": "^3.2.0", - "lite-server": "^2.2.2", - "typescript": "^2.2.2", + "concurrently": "3.2.0", + "lite-server": "2.2.2", + "typescript": "2.2.2", "canonical-path": "0.0.2", - "tslint": "^3.15.1", - "lodash": "^4.16.4", - "jasmine-core": "~2.4.1", - "karma": "^1.3.0", - "karma-chrome-launcher": "^2.0.0", - "karma-cli": "^1.0.1", - "karma-jasmine": "^1.0.2", - "karma-jasmine-html-reporter": "^0.2.2", - "protractor": "~4.0.14", - "rimraf": "^2.5.4", - "@types/node": "^6.0.46", + "tslint": "3.15.1", + "lodash": "4.16.4", + "jasmine-core": "2.4.1", + "karma": "1.3.0", + "karma-chrome-launcher": "2.0.0", + "karma-cli": "1.0.1", + "karma-jasmine": "1.0.2", + "karma-jasmine-html-reporter": "0.2.2", + "protractor": "4.0.14", + "rimraf": "2.5.4", + "@types/node": "6.0.46", "@types/jasmine": "2.5.36" }, "repository": {} diff --git a/src/app/i18n-providers.ts b/src/app/i18n-providers.ts new file mode 100644 index 000000000..76ee311c5 --- /dev/null +++ b/src/app/i18n-providers.ts @@ -0,0 +1,34 @@ +import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID, MissingTranslationStrategy } from '@angular/core'; +import { CompilerConfig } from '@angular/compiler'; + +export function getTranslationProviders(): Promise<Object[]> { + + // Get the locale id from the global + const locale = document['locale'] as string; + + // return no providers if fail to get translation file for locale + const noProviders: Object[] = []; + + // No locale or French: no translation providers + if (!locale || locale === 'fr-FR') { + return Promise.resolve(noProviders); + } + + // Ex: 'locale/messages.es.xlf` + const translationFile = `./locale/messages.${locale}.xlf`; + + return getTranslationsWithSystemJs(translationFile) + .then((translations: string) => [ + { provide: TRANSLATIONS, useValue: translations }, + { provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }, + { provide: LOCALE_ID, useValue: locale }, + { provide: CompilerConfig, useValue: new CompilerConfig({ missingTranslation: MissingTranslationStrategy.Error }) } + ]) + .catch(() => noProviders); // ignore if file not found +} + +declare var System: any; + +function getTranslationsWithSystemJs(file: string) { + return System.import(file + '!text'); // relies on text plugin +} diff --git a/src/app/param-input/param-input.component.html b/src/app/param-input/param-input.component.html index 265cb5a83..87e6d7b2e 100644 --- a/src/app/param-input/param-input.component.html +++ b/src/app/param-input/param-input.component.html @@ -1,5 +1,11 @@ +<!-- +format de l'attribut i18n : +i18n="<meaning>|<description>@@<custom id>" +<p i18n="titre saisie|Titre du contrôle de saisie de paramètre@@titre_saisie_param">Saisie de paramètre</p> +--> +<p i18n="@@titre_saisie_param">Saisie de paramètre</p> <md-input-container> - <input mdInput placeholder="{{_paramDef.symbol}}" [ngModel]="_uiValue.uncheckValueString" (ngModelChange)="setValue($event)" + <input mdInput placeholder="{{_paramDef.symbol}}" [ngModel]="_uiValue.uncheckedValueString" (ngModelChange)="setValue($event)" /> <md-hint>{{_message}}</md-hint> </md-input-container> diff --git a/src/app/param-input/param-input.component.ts b/src/app/param-input/param-input.component.ts index ead9e0285..447b8a6ea 100644 --- a/src/app/param-input/param-input.component.ts +++ b/src/app/param-input/param-input.component.ts @@ -3,7 +3,7 @@ import { Component, Input, forwardRef, OnInit, DoCheck, ChangeDetectorRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl } from '@angular/forms'; -import { ParamDefinition, NumericalString } from 'jalhyd'; +import { ParamDefinition, NumericalString, Internationalisation, Language, ErrorMessage } from 'jalhyd'; import { ParamService } from '../param-service/param.service'; @@ -55,7 +55,6 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec /** * valeur dans le contrôle (saisie par l'utilisateur) */ - // private _uiValue: string; private _uiValue: NumericalString; constructor(private paramService: ParamService, private changeDetector: ChangeDetectorRef) { @@ -93,6 +92,10 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec ngOnInit() { // retrieve parameter from symbol this._paramDef = this.paramService.getParameter(this._paramSymbol); + + let docLocale: string = document['locale'] as string; + Internationalisation.getInstance().setLocale(docLocale); + console.log("doc locale " + docLocale); } // private getValue() { @@ -146,11 +149,22 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec this._paramDef.checkValue(v.numericalValue); } catch (e) { - this._message = e; + if (e instanceof ErrorMessage) + this._message = Internationalisation.getInstance().localizeErrorMessage(e); + else + this._message = "invalid value"; + } + } + else { + switch (Internationalisation.getInstance().lang) { + case Language.FRENCH: + this._message = "Veuillez entrer une valeur numérique"; + break; + + default: + this._message = "Please enter a numerical value"; } } - else - this._message = "Please enter a numerical value"; this.log("updateMessage end :" + this.getSParam() + this.getSfromUI() + this.getSUIvalue(v) + " message=" + this._message); } @@ -192,7 +206,7 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec private log(m: string) { let t: number = new Date().getTime() - ParamInputComponent._startTime; - console.log("ParamInputComponent(" + this._id + ") " + t + " : " + m); + // console.log("ParamInputComponent(" + this._id + ") " + t + " : " + m); } // ControlValueAccessor interface diff --git a/src/index.html b/src/index.html index ca397ac50..132635677 100644 --- a/src/index.html +++ b/src/index.html @@ -16,6 +16,18 @@ <script src="systemjs.config.js"></script> <script> + // Get the locale id somehow + document.locale = 'fr-FR'; + // document.locale = 'en'; + + // Map to the text plugin + System.config({ + map: { + text: 'systemjs-text-plugin.js' + } + }); + + // Launch the app System.import('main.js').catch(function (err) { console.error(err); }); </script> diff --git a/src/locale/messages.en.xlf b/src/locale/messages.en.xlf new file mode 100644 index 000000000..9c90b3e35 --- /dev/null +++ b/src/locale/messages.en.xlf @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> + <file source-language="en" datatype="plaintext" original="ng2.template"> + <body> + <trans-unit id="titre_saisie_param" datatype="html"> + <target>Parameter input</target> + </trans-unit> + </body> + </file> +</xliff> diff --git a/src/main.ts b/src/main.ts index 311c44b76..d58d8c33d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,10 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { getTranslationProviders } from './app/i18n-providers'; import { AppModule } from './app/app.module'; -platformBrowserDynamic().bootstrapModule(AppModule); +//platformBrowserDynamic().bootstrapModule(AppModule); +getTranslationProviders().then(providers => { + const options = { providers }; + platformBrowserDynamic().bootstrapModule(AppModule, options); +}); diff --git a/src/systemjs-text-plugin.js b/src/systemjs-text-plugin.js new file mode 100644 index 000000000..fb7224a63 --- /dev/null +++ b/src/systemjs-text-plugin.js @@ -0,0 +1,20 @@ +/* + SystemJS Text plugin from + https://github.com/systemjs/plugin-text/blob/master/text.js +*/ +exports.translate = function (load) { + if (this.builder && this.transpiler) { + load.metadata.format = 'esm'; + return 'exp' + 'ort var __useDefault = true; exp' + 'ort default ' + JSON.stringify(load.source) + ';'; + } + + load.metadata.format = 'amd'; + return 'def' + 'ine(function() {\nreturn ' + JSON.stringify(load.source) + ';\n});'; +} + + +/* +Copyright 2017 Google Inc. All Rights Reserved. +Use of this source code is governed by an MIT-style license that +can be found in the LICENSE file at http://angular.io/license +*/ \ No newline at end of file -- GitLab