Dino
Dino

Reputation: 8292

Angular i18n for text containing routerLink and requires different word order

I am struggling to find the most efficient way to translate the text containing routerLink or text where some words should be wrapped in html tags ( word ).

Let's see how it looks without the i18n implementation:

example.component.html

<div>
 Hello and welcome to this test example. In order to proceed click on this 
 <a [routerLink]="['settings/subscription']">Link</a>
</div>

Now let's add i18n to it, and use one possible approach to deal with the routerLink: en.json

{
  "WELCOME_LABEL": "Hello and welcome to this test example. In order to proceed click on this,
  "LINK_LABEL": "link"
}

example.component.html

<div>
 {{'WELCOME_LABEL' | translate}} 
 <a [routerLink]="['settings/subscription']">{{'LINK_LABEL' | translate}}</a>
</div>

The problem with this approach is that different languages could have words in a different order. For example. "Please click on this link" in some other language could have the order where "link" is at the begining or in the middle of a sentence.

Is there some general / official approach to deal with this situation?

The one way how I could solve it is to get the current locale in the component and then do the if check in the template based on it.

I don't like this way because I'm kind of stepping out of i18n practice, and creating separate JSON objects based on locale just to be able to fit the word ordering needs.

example.component.ts

constructor(
    @Inject( LOCALE_ID ) protected localeId: string
) {
    console.log(this.localeId);
}

example.component.html

<div *ngIf="localeId === 'en-Us'">
 {{'WELCOME_LABEL_EN' | translate}} 
 <a [routerLink]="['settings/subscription']">{{'LINK_LABEL_EN' | translate}}</a>
</div>
<div *ngIf="localeId === 'otherLanguage'">
 {{'WELCOME_LABEL_1_OTHER' | translate}} 
 <a [routerLink]="['settings/subscription']">{{'LINK_LABEL_OTHER' | translate}}</a>
 {{'WELCOME_LABEL_2_OTHER' | translate}} 
</div>

Upvotes: 4

Views: 5631

Answers (2)

Kapcash
Kapcash

Reputation: 6919

What if you simply define the <div> in three parts? Like, the text start, the link, then the end.

<div>
  {{'WELCOME_LABEL_START' | translate}}
  <a [routerLink]="['settings/subscription']">{{'LINK_LABEL' | translate}}</a>
  {{'WELCOME_LABEL_END' | translate}}
</div>

This way, according to the language, you just have to define the sentence in two parts.

{
  "WELCOME_LABEL_START": "In order to proceed, click on this",
  "LINK_LABEL": "link",
  "WELCOME_LABEL_END": " whatever language you have."
}

And you just let the start / end empty if unnecessary.

Upvotes: 1

Neven.Leung
Neven.Leung

Reputation: 860

Angular doesn't seem to support passing directive and none-HTML element as innerHTML. I don't try it, but it needs to be noticed.


You can pass the whole sentence as innerHTML for the translation, which includs the link element. In this way, you can output the content dynamically.

Template:

<span [innerHTML]="key | translate"></span>

JSON:

{
  "key": "Please click on <a href='abc.com'>this link</a>."
}

Upvotes: 1

Related Questions