Nowadays, a common scenario in front-end applications is to have the ability to translate labels and locate numbers, dates, currency and so on when the user clicks over a language selector or similar. devon4ng and specifically Angular has a default mechanism in order to fill the gap of such features, and besides there are some wide used libraries that make even easier to translate applications.
More info at Angular i18n official documentation
The official approach could be a bit complicated, therefore the recommended one is to use the recommended library NGX Translate from http://www.ngx-translate.com/.
In order to include this library in your devon4ng Angular >= 4.3 project you will need to execute in a terminal:
$ npm install @ngx-translate/core @ngx-translate/http-loader --save
# or if you use yarn
$ yarn add @ngx-translate/core @ngx-translate/http-loader
-
@ngx-translate/core is the core library to provide i18n capabilities.
-
@ngx-translate/http-loader is a loader for ngx-translate that loads translations using http.
Depending on the volume of the devon4ng application we will include the NGX Translate library in the app.module.ts
or in the core.module.ts
transversal to the application.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
Next, an exported function for factories has to be created:
// AoT requires an exported function for factories
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http);
}
@NgModule({
imports: [
BrowserModule,
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
})
],
bootstrap: [AppComponent]
})
export class AppModule { } // or CoreModule
The TranslateHttpLoader
also has two optional parameters:
-
prefix: string = "/assets/i18n/"
-
suffix: string = ".json"
By using those default parameters, it will load the translations files for the lang "en" from: /assets/i18n/en.json
. In general, any translation file will loaded from the /assets/i18n/
folder.
Those parameters can be changed in the HttpLoaderFactory
method just defined. For example if you want to load the "en" translations from /public/lang-files/en-lang.json
you would use:
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, "/public/lang-files/", "-lang.json");
}
For now this loader only support the json format.
ℹ️
|
If you’re still on Angular < 4.3, please use Http from @angular/http with http-loader@0.1.0 .
|
In order to translate any label in any HTML template you will need to use the translate
pipe available:
{{ 'HELLO' | translate }}
An optional parameter from the component TypeScript class could be included as follows:
{{ 'HELLO' | translate:param }}
So, param
has to be defined in the class. The default language used is defined as follows:
// imports
@Component({
selector: 'app',
template: `
<div>{{ 'HELLO' | translate }}</div> // Without param
<div>{{ 'HELLO' | translate:param }}</div> // With param
`
})
export class AppComponent {
// This param will be used in the translation
param = { value: 'world' };
constructor(translate: TranslateService) {
// this language will be used as a fallback when a translation isn't found in the current language
translate.setDefaultLang('en');
// the lang to use, if the lang isn't available, it will use the current loader to get them
translate.use('en');
}
}
In order to change the language used you will need to create a button or selector that calls the this.translate.use(language: string)
method from TranslateService
. For example:
toggleLanguage(option) {
this.translate.use(option);
}
The translations will be included in the en.json
, es.json
, de.json
, etc. files inside the /assets/i18n
folder. For example en.json
would be (using the previous param):
{
"HELLO": "hello"
}
Or with an optional param:
{
"HELLO": "hello {{value}}"
}
The TranslateParser
understands nested JSON objects. This means that you can have a translation that looks like this:
{
"HOME": {
"HELLO": "hello {{value}}"
}
}
In order to access access the value, use the dot notation, in this case HOME.HELLO
.
If you need to access translations in any component or service you can do it injecting the Translateservice
into them:
translate.get('HELLO', {value: 'world'}).subscribe((res: string) => {
console.log(res);
//=> 'hello world'
});
The use of pipes can be possible too:
template:
<div>{{ 'HELLO' | translate:param }}</div>
component:
param = {value: 'world'};
Finally, it can also be used with directives:
<div [translate]="'HELLO'" [translateParams]="{value: 'world'}"></div>
or, using the content of your element as a key
<div translate [translateParams]="{value: 'world'}">HELLO</div>
❗
|
You can find a complete example at https://github.com/devonfw/devon4ng-application-template. |
Please, visit https://github.com/ngx-translate/core for more info.