Contribute to help us improve!
Are there edge cases or problems that we didn't consider? Is there a technical pitfall that we should add? Did we miss a comma in a sentence?
If you have any input for us, we would love to hear from you and appreciate every contribution. Our goal is to learn from projects for projects such that nobody has to reinvent the wheel.
Let's collect our experiences together to make room to explore the novel!
To contribute click on Contribute to this page on the toolbar.
Internationalization
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
devon4ng i18n approach
The official approach could be a bit complicated, therefore the recommended one is to use the recommended library Transloco from https://github.com/ngneat/transloco/.
Install and configure Transloco
In order to include this library in your devon4ng Angular >= 7.2 project you will need to execute in a terminal:
$ ng add @ngneat/transloco
bash
As part of the installation process you’ll be presented with questions; Once you answer them, everything you need will automatically be created for you.
-
First, Transloco creates boilerplate files for the requested translations.
-
Next, it will create a new file,
transloco-root.module.ts
which exposes an Angular’smodule
with a default configuration, and inject it into theAppModule
.
import { HttpClient } from '@angular/common/http'; import { TRANSLOCO_LOADER, Translation, TranslocoLoader, TRANSLOCO_CONFIG, translocoConfig, TranslocoModule } from '@ngneat/transloco'; import { Injectable, NgModule } from '@angular/core'; import { environment } from '../environments/environment'; @Injectable({ providedIn: 'root' }) export class TranslocoHttpLoader implements TranslocoLoader { constructor(private http: HttpClient) {} getTranslation(lang: string) { return this.http.get<Translation>(`/assets/i18n/${lang}.json`); } } @NgModule({ exports: [ TranslocoModule ], providers: [ { provide: TRANSLOCO_CONFIG, useValue: translocoConfig({ availableLangs: ['en', 'es'], defaultLang: 'en', // Remove this option if your application doesn't support changing language in runtime. reRenderOnLangChange: true, prodMode: environment.production, }) }, { provide: TRANSLOCO_LOADER, useClass: TranslocoHttpLoader } ] }) export class TranslocoRootModule {}
typescript
As you might have noticed it also set an HttpLoader into the module’s providers. The HttpLoader is a class that implements the TranslocoLoader interface. It’s responsible for instructing Transloco how to load the translation files. It uses Angular HTTP client to fetch the files, based on the given path.
|
Usage
In order to translate any label in any HTML template you will need to use the transloco
pipe available:
{{ 'HELLO' | transloco }}
html
An optional parameter from the component TypeScript class could be included as follows:
{{ 'HELLO' | transloco: { value: dynamic } }}
html
It is possible to use with inputs
:
<span [attr.alt]="'hello' | transloco">Attribute</span>
<span [title]="'hello' | transloco">Property</span>
html
In order to change the language used you will need to create a button or selector that calls the this.translocoService.use(language: string)
method from TranslocoService
. For example:
export class AppComponent { constructor(private translocoService: TranslocoService) {} changeLanguage(lang) { this.translocoService.setActiveLang(lang); } }
typescript
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 parameter):
{
"HELLO": "hello"
}
json
Or with an optional parameter:
{
"HELLO": "hello {{value}}"
}
json
Transloco understands nested JSON objects. This means that you can have a translation that looks like this:
{
"HOME": {
"HELLO": "hello {{value}}"
}
}
json
In order to access access the value, use the dot notation, in this case HOME.HELLO
.
Using the service, pipe or directive
Structural Directive
Using a structural directive is the recommended approach. It’s DRY and efficient, as it creates one subscription per template:
<ng-container *transloco="let t"> <p>{{ t('title') }}</p> <comp [title]="t('title')"></comp> </ng-container>
typescript
Note that the t
function is memoized. It means that given the same key
it will return the result directly from the cache.
We can pass a params
object as the second parameter:
<ng-container *transloco="let t"> <p>{{ t('name', { name: 'Transloco' }) }}</p> </ng-container>
typescript
We can instruct the directive to use a different language in our template:
<ng-container *transloco="let t; lang: 'es'"> <p>{{ t('title') }}</p> </ng-container>
typescript
Pipe
The use of pipes can be possible too:
template:
<div>{{ 'HELLO' | transloco:param }}</div>
typescript
component:
param = {value: 'world'};
typescript
Attribute Directive
The last option available with transloco
is the attribute directive:
<div transloco="HELLO" [translocoParams]="{ value: 'world' }"></div>
typescript
Service
If you need to access translations in any component or service you can do it injecting the TranslocoService
into them:
// Sync translation translocoService.translate('HELLO', {value: 'world'}); // Async translation translocoService.selectTranslate('HELLO', { value: 'world' }).subscribe(res => { console.log(res); //=> 'hello world' });
typescript
You can find a complete example at https://github.com/devonfw/devon4ng-application-template. |
Please, visit https://github.com/ngneat/transloco/ for more info.