lang:angular:traduction
Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
lang:angular:traduction [2021/08/23 02:10] – Création avec "@angular/localize" root | lang:angular:traduction [2021/10/10 18:49] (Version actuelle) – [Sources] : ajout du lazy load pour ngx-translate root | ||
---|---|---|---|
Ligne 8: | Ligne 8: | ||
* Pas de dépendances externes, | * Pas de dépendances externes, | ||
- | * Le texte est traduit en dur dans le code généré, | + | * Le texte est traduit en dur dans le code généré, pas de pipe, |
- | * On compile une fois, on génère un site par langue. | + | * On compile une fois mais on génère un site par langue. |
Inconvénient : | Inconvénient : | ||
* On ne peut pas traduire des librairies, [[https:// | * On ne peut pas traduire des librairies, [[https:// | ||
- | * On génère un site autonome | + | * On génère un site par langue. Cela duplique les '' |
* Il n'est que possible de générer la liste des textes à traduire. Il n'est pas possible de mettre à jour une liste des traductions. [[https:// | * Il n'est que possible de générer la liste des textes à traduire. Il n'est pas possible de mettre à jour une liste des traductions. [[https:// | ||
+ | * Il n'est pas possible de changer la langue sans changer de page HTML, | ||
====Initialisation==== | ====Initialisation==== | ||
Ligne 134: | Ligne 136: | ||
</ | </ | ||
=====@ngx-translate/ | =====@ngx-translate/ | ||
+ | |||
+ | [[https:// | ||
====Présentation==== | ====Présentation==== | ||
- | L' | + | L' |
+ | |||
+ | Avantages : | ||
+ | |||
+ | * Un seul site dont la langue est changeable sans recharger, | ||
+ | * On peut avoir un fichier de traduction distinct par librairie et par application [[https:// | ||
+ | |||
+ | Inconvénient : | ||
+ | |||
+ | * Comme c'est une dépendance externe, on ne profite pas d'une intégration profonde des avantages du compilateur, | ||
+ | * Dépendance externe, | ||
+ | * Le texte est traduit à la volée. Avant la conversion, le texte est manquant. Cela peut donc réduire l' | ||
+ | * Nécessite de définir l' | ||
+ | |||
+ | ====Initialisation==== | ||
+ | |||
+ | ===Installation=== | ||
+ | |||
+ | <code bash> | ||
+ | npm i --save @ngx-translate/ | ||
+ | </ | ||
+ | |||
+ | ===Configuration=== | ||
+ | |||
+ | Il n'y a besoin de rien. | ||
+ | |||
+ | ===Sources=== | ||
+ | |||
+ | Un exemple simple : [[https:// | ||
+ | |||
+ | Un autre exemple plus complet avec uniquement une application: | ||
+ | |||
+ | Exemple bien détaillé avec une librairie et une application: | ||
+ | |||
+ | * Librairie | ||
+ | |||
+ | Il faut exporter le module de traduction. [[https:// | ||
+ | |||
+ | <file javascript lib-jessica/ | ||
+ | import { TranslateModule } from ' | ||
+ | |||
+ | @NgModule({ | ||
+ | imports: [..., TranslateModule], | ||
+ | exports: [ | ||
+ | ..., | ||
+ | TranslateModule | ||
+ | ] | ||
+ | }) | ||
+ | </ | ||
+ | |||
+ | * Application | ||
+ | |||
+ | <file javascript app-main/ | ||
+ | import { TranslateService } from ' | ||
+ | |||
+ | export class AppComponent { | ||
+ | ... | ||
+ | |||
+ | constructor(public translate: TranslateService) { | ||
+ | translate.addLangs([' | ||
+ | translate.setDefaultLang(' | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | <file javascript app-main/ | ||
+ | import { HttpClient } from ' | ||
+ | import { TranslateLoader } from ' | ||
+ | import { forkJoin, Observable } from ' | ||
+ | import { map } from ' | ||
+ | |||
+ | export class MultiTranslateHttpLoader implements TranslateLoader { | ||
+ | constructor( | ||
+ | private http: HttpClient, | ||
+ | public resources: { prefix: string; suffix: string }[] = [ | ||
+ | { | ||
+ | prefix: ' | ||
+ | suffix: ' | ||
+ | } | ||
+ | ] | ||
+ | ) {} | ||
+ | |||
+ | public getTranslation(lang: | ||
+ | return forkJoin( | ||
+ | this.resources.map((config) => { | ||
+ | return this.http.get(`${config.prefix}${lang}${config.suffix}`); | ||
+ | }) | ||
+ | ).pipe( | ||
+ | map((response) => { | ||
+ | return response.reduce((a, | ||
+ | return Object.assign(a, | ||
+ | }); | ||
+ | }) | ||
+ | ); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <file javascript app-main/ | ||
+ | import { HttpClient, HttpClientModule } from ' | ||
+ | import { TranslateModule, | ||
+ | |||
+ | import { MultiTranslateHttpLoader } from ' | ||
+ | |||
+ | export function createTranslateLoader(http: | ||
+ | return new MultiTranslateHttpLoader(http, | ||
+ | { prefix: ' | ||
+ | { prefix: ' | ||
+ | ]); | ||
+ | } | ||
+ | |||
+ | @NgModule({ | ||
+ | ..., | ||
+ | imports: [ | ||
+ | ..., | ||
+ | HttpClientModule, | ||
+ | TranslateModule.forRoot({ | ||
+ | loader: { | ||
+ | provide: TranslateLoader, | ||
+ | useFactory: createTranslateLoader, | ||
+ | deps: [HttpClient] | ||
+ | }, | ||
+ | defaultLanguage: | ||
+ | }) | ||
+ | ], | ||
+ | ... | ||
+ | }) | ||
+ | ... | ||
+ | </ | ||
+ | |||
+ | ===Lazy load=== | ||
+ | |||
+ | Pour éviter de devoir charger toutes les langues possibles, il faut charger dynamiquement les locales. | ||
+ | |||
+ | <code javascript> | ||
+ | import { registerLocaleData } from ' | ||
+ | |||
+ | const locale = await import( | ||
+ | /* webpackInclude: | ||
+ | ' | ||
+ | ); | ||
+ | registerLocaleData(locale.default, | ||
+ | translate.use(selectedLang); | ||
+ | </ | ||
+ | |||
+ | Ici, translate est '' | ||
+ | |||
+ | L' | ||
+ | |||
+ | [[https:// | ||
+ | ====Traduction==== | ||
+ | |||
+ | * HTML | ||
+ | |||
+ | <code xml> | ||
+ | {{ ' | ||
+ | </ | ||
+ | |||
+ | * Traduction | ||
+ | |||
+ | <file javascript app-main/ | ||
+ | { | ||
+ | " | ||
+ | " | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====Tests==== | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | Pour les tests unitaires (pas end-to-end), | ||
+ | |||
+ | Dans le composant principal de l' | ||
+ | |||
+ | <file javascript app-main/ | ||
+ | import { | ||
+ | TranslateFakeLoader, | ||
+ | TranslateLoader, | ||
+ | TranslateModule | ||
+ | } from ' | ||
+ | |||
+ | describe(' | ||
+ | beforeEach(async () => { | ||
+ | await TestBed.configureTestingModule({ | ||
+ | imports: [ | ||
+ | ..., | ||
+ | TranslateModule.forRoot({ | ||
+ | loader: { | ||
+ | provide: TranslateLoader, | ||
+ | useClass: TranslateFakeLoader | ||
+ | } | ||
+ | }) | ||
+ | ], | ||
+ | ... | ||
+ | </ | ||
+ | |||
+ | Dans chaque composant de l' | ||
+ | |||
+ | <file javascript app-main/ | ||
+ | import { TranslateMockPipe } from ' | ||
+ | |||
+ | describe(' | ||
+ | beforeEach(async () => { | ||
+ | await TestBed.configureTestingModule({ | ||
+ | declarations: | ||
+ | ..., | ||
+ | TranslateMockPipe | ||
+ | ] | ||
+ | }).compileComponents(); | ||
+ | }); | ||
+ | </ | ||
+ | |||
+ | Dans chaque composant de la librairie, on utilise le même pipe de traduction : | ||
+ | |||
+ | <file javascript lib-jessica/ | ||
+ | import { TranslateMockPipe } from ' | ||
+ | |||
+ | describe(' | ||
+ | beforeEach(async () => { | ||
+ | await TestBed.configureTestingModule({ | ||
+ | ..., | ||
+ | declarations: | ||
+ | }).compileComponents(); | ||
+ | }); | ||
+ | </ | ||
+ | |||
+ | <file javascript lib-library/ | ||
+ | import { Pipe, PipeTransform } from ' | ||
+ | |||
+ | @Pipe({ | ||
+ | name: ' | ||
+ | }) | ||
+ | export class TranslateMockPipe implements PipeTransform { | ||
+ | public name = ' | ||
+ | |||
+ | public transform(query: | ||
+ | return query; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <file javascript projects/ | ||
+ | export * from ' | ||
+ | </ | ||
+ | |||
+ | =====globalize.js===== | ||
+ | |||
+ | ====Présentation==== | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | C'est une librairie JavaScript (compatible TypeScript via '' | ||
+ | |||
+ | Les données de localisation viennent d'un paquet npm '' | ||
+ | |||
+ | ====Utilisation==== | ||
+ | |||
+ | La librairie est simple à utiliser. | ||
+ | |||
+ | Ci-dessous, un exemple pour convertir un nombre dans une certaine langue vers une autre langue. | ||
+ | |||
+ | La particularité ici est l' | ||
+ | |||
+ | Il est nécessaire d' | ||
+ | |||
+ | <file javascript tsconfig.json> | ||
+ | { | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ], | ||
+ | ... | ||
+ | } | ||
+ | }, | ||
+ | ... | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code javascript> | ||
+ | import likelySubtags from ' | ||
+ | import numberingSystems from ' | ||
+ | |||
+ | import * as globalize from ' | ||
+ | import ' | ||
+ | |||
+ | globalize.load([likelySubtags, | ||
+ | |||
+ | const cldrLocale = await import( | ||
+ | /* webpackInclude: | ||
+ | ' | ||
+ | ); | ||
+ | |||
+ | globalize.load(cldrLocale.default); | ||
+ | |||
+ | let parserFrom = globalize.locale(from).numberParser(); | ||
+ | let parserTo = globalize.locale(to).numberFormatter(); | ||
+ | </ | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | L' |
lang/angular/traduction.1629677411.txt.gz · Dernière modification : 2021/08/23 02:10 de root