Extraction tool + service to add support for code translations in Angular using the same implementation that is used for template translations.
❗ Out of Date: You should use @angular/localize
Angular 9 now supports code based localization via
$localize:`meaning|description@@id:message`
Locl is the new tool that lets you extract the string from your files (since angular CLI again does not support it yet)
- Replace all occurrences with the new syntax:
- You can use this regex in VSCode:
Search:
Replace:
(.*)this\.i18n\(\{\n[\s\/]*meaning:[\s\n]*'(.*)',\n[\s\/]*description:[\s\n]*'(.*)',\n[\s\/]*id:[\s\n]*'(.*)',\n[\s\/]*value:[\s\n]*['`](.*)['`]\n[\s\/]*\}\)
$1$localize`:$5|$3@@$4:$2`
- You can use this regex in VSCode:
Search:
- Remove all i18n usings such as:
import { I18n } from '@ngx-translate/i18n-polyfill';
private i18n: I18n
Some Caveats:
- be aware of existing tranlation functions that are named differently or whose attributes are in a different order
- be aware that
meaning
,description
andid
can no longer contain:
-symbol - be aware that
message
should not contain ```
This library is a speculative polyfill, it means that it's supposed to replace an API that is coming in the future. Once code translations are available in Angular, this library will be deprecated. But since it's a polyfill, we expect the API to be pretty similar. If the API is different, a migration tool will be provided if it's possible and necessary.
To install this library, run:
$ npm install @ngx-translate/i18n-polyfill --save
The API is quite simple, you get a service called I18n
that takes 2 parameters: the content to translate
and the parameters (optional). It'll return the content translated synchronously.
The signature of the service is:
I18n: (def: string | I18nDef, params?: {[key: string]: any}) => string
.
The content can be a simple string or an i18n definition:
I18nDef: {
value: string;
id?: string;
meaning?: string;
description?: string;
}
Prepare your application to use i18n, as described on the official documentation, and then provide the TRANSLATIONS
file and I18n
service in your module or component:
import { BrowserModule } from '@angular/platform-browser';
import {
NgModule,
TRANSLATIONS
} from '@angular/core';
import { AppComponent } from './app.component';
// Import the service
import { I18n } from '@ngx-translate/i18n-polyfill';
declare const require; // Use the require method provided by webpack
const translations = require(`raw-loader!../locale/messages.fr.xlf`).default;
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [
{provide: TRANSLATIONS, useValue: translations},
I18n
],
bootstrap: [AppComponent]
})
export class AppModule { }
To dynamically load the translations file based on locale you can use a factory provider.
Replace
{provide: TRANSLATIONS, useValue: translations}
with:
{
provide: TRANSLATIONS,
useFactory: (locale) => {
locale = locale || 'en'; // default to english if no locale provided
return require(`raw-loader!../locale/messages.${locale}.xlf`).default;
},
deps: [LOCALE_ID]
}
Once the I18n
service and TRANSLATIONS
are imported & provided, you can use the service in your Angular application:
import { Component } from "@angular/core";
import { I18n } from "@ngx-translate/i18n-polyfill";
@Component({
selector: "app-root",
template: "./app.component.html"
})
export class AppComponent {
constructor(i18n: I18n) {
console.log(i18n("This is a test {{myVar}} !", {myVar: "^_^"}));
}
}
You can use strings, interpolations and ICU expressions exactly like in template translations. Don't use elements, it makes no sense and you should use a template translation for that instead.
Interpolations will be replaced by the values that you provide in the object that you pass as the second parameter of the service.
You should use the same names for your keys than the ones that you use in your interpolations.
For example: i18n("This is a test {{myVar}} !", {myVar: "^_^"})
There is an extraction tool called ngx-extractor
that will extract the messages.
You should first extract the messages from the templates using the ng-xi18n
extraction tool from @angular/compiler-cli
which will create an xliff or xmb file, and then run ngx-extractor
on the same file to add the messages extracted from your code.
The messages will be merged.
The cli parameters are the following:
-
--input
(alias:-i
, required): Paths you would like to extract strings from. You can use path expansion, glob patterns and multiple paths.Example:
-i src/**/*.ts
. -
--format
(alias-f
, optional, defaultxlf
): Output format, either xlf, xlf2 or xmb.Example:
-f xlf
. -
--outFile
(alias-o
, required): Path and name of the file where you would like to save extracted strings. If the file exists then the messages will be merged.Example:
-o src/i18n/source.xlf
. -
--locale
(alias-l
, optional, default:en
): Source language of the application.Example:
-l de
.
And here is how you would extract the messages from your ng cli application to a file named src/i18n/source.xlf:
- run ng-xi18n:
ng xi18n -of i18n/source.xlf -f xlf --locale en
- run ng-extractor:
ngx-extractor -i src/**/*.ts -f xlf -o src/i18n/source.xlf
The service was written using source code from Angular and the extraction tool used code from ngx-translate-extract by @biesbjerg.
MIT © Olivier Combe