lang:angular:traduction
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| lang:angular:traduction [2021/08/23 23:38] – Mise à jour de "@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 mais 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 : | ||
| Ligne 16: | Ligne 17: | ||
| * On génère un site par langue. Cela duplique les '' | * 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.1629754736.txt.gz · Dernière modification : de root
