1

I all ;)

I'm new to angular and I want to use i18n from angular. But when I want to translate a text from angular class with use of interpolation {{}}, I don't know how to do this.

I have a component toolbar, this toolbar contains a title who change when an event is fired. this Event contain a title to display. But how can I translate this title with i18n ?

I tried with select: {title, select, title1 {my title is 1} title2 {my title is 2} title3 {my title is 3}} But I think is not a great solution

Component class :

@Component({
  selector: 'toolbar',
  templateUrl: './toolbar.component.html',
  styles: []
})
export class StartComponent implements OnInit {
  public title : string;

  constructor(private communicate: CommunicateService) {
  }

  ngOnInit() {
      this.subscription = this.communicate.getTitle().subscribe(
              title => this.title = title,
              (err: any) => console.error(err)
          );
  }
}

Html template :

<div class="toolbar">{{title}}</div>

And so, my question is... How can I translate title ? I think there are some other problem like that so all advice is appreciated.

Thanks in advance to help me :)

Maximilien Faure
  • 119
  • 1
  • 11
  • 1
    Use can use translate pipe :
    {{title | translate }}
    – ilyas shabi Jul 10 '19 at 13:53
  • How to use this translate pipe ? did it part of angular core ? If I do like that I should import a static json file corresponding to the translation no ? – Maximilien Faure Jul 10 '19 at 14:00
  • The pipe should be avoided where possible. Here it is possible. Please use
    {{title}}
    Is your project setup to use i18n already or is the setup a part of your question?
    – MoxxiManagarm Jul 10 '19 at 14:04
  • I'm searching the best way to translate my futur angular project so no, my project dosen't use i18n already. But I never see this syntaxe :
    text
    could you give me a link to the documentation please ? It's a third party library ?
    – Maximilien Faure Jul 10 '19 at 14:52

1 Answers1

2

You can use interpolations and html markup inside of your translations.

See the documentation.

So a simple i18n tag like <div class="toolbar" i18n>Welcome to {{companyName}}!</div> should do it.

In the rendered .xlf file that would look something like:

<trans-unit id="91073dbc0b03be401d8c83b8e9c1513c3fa87b14" datatype="html">
  <source>Welcome to <x id="INTERPOLATION" equiv-text="{{ companyName }}"/>!</source>
    <context-group purpose="location">
    <context context-type="sourcefile">app/login/welcome-screen/welcome-screen.template.html</context>
    <context context-type="linenumber">1</context>
  </context-group>
</trans-unit>

I hope that answers your question :)

Edit based on the comments below:

To solve your particular problem you could write your start.template.html like:

<div style="display: none">
   <span #firstTitle i18n>First title</span>
   <span #secondTitle i18n>Second title</span>
   <span #thirdTitle i18n>Third title</span>
</div>
<div>{{ title }}</div>

To write hidden elements with i18n tags is a common workaround since you can't translate inside components or services right now. (for more information see this post)

In the start.component.ts you then can subscribe to router changes and set the corresponding title like:

@Component({
  selector: 'toolbar',
  templateUrl: './toolbar.component.html',
  styles: []
})
export class StartComponent implements OnInit {
  public title : string;
  @ViewChild('firstTitle') firstTitle: ElementRef<HTMLSpanElement>;
  @ViewChild('secondTitle') secondTitle: ElementRef<HTMLSpanElement>;
  @ViewChild('thirdTitle') thirdTitle: ElementRef<HTMLSpanElement>;

  constructor(private router: Router) {}

  ngOnInit() {
     this.router.events.subscribe((event) => {
       if(event.url) {
         setTitleByUrl(event.url);
       }
     });
   }

   private setTitleByUrl(url: string) {
     if (url === 'firstUrl') {
        title = this.firstTitle.nativeElement.textContent;
     } else if (url === 'secondUrl') {
        title = this.secondTitle.nativeElement.textContent;
     } else if (url === 'thirdUrl') {
        title = this.thirdTitle.nativeElement.textContent;
     }
   }
}

Here you subscribe to the Angular router (for more details look here) and set the title.

sevic
  • 879
  • 11
  • 36
  • Yes but this dosen't answer to what I said (sorry If my question isn't good formulated but I'm not very good in english ^^' ). What I want is if I have got :
    {{title}}
    all text is in title variable. There is no text in the HTML
    – Maximilien Faure Jul 10 '19 at 14:47
  • so you would like to translate whatever value the variable `title` has automatically? what does the `this.communicate.getTitle()` function look like? – sevic Jul 10 '19 at 14:58
  • Yes it's that, this.communicate.getTitle() give a title depending on what is the current URL (on page1 => page1 title, on page2 => page2 title, and so on) (it's perhaps that that is bad ? ) – Maximilien Faure Jul 10 '19 at 15:11
  • hmmmm so you have the strings hardcoded in the service and depending on the current route you return the corresponding title? if they are hardcoded in the service, in my humble opinion it would be cleaner to move them to the template. `
    Some title
    `
    – sevic Jul 10 '19 at 15:21
  • Yes I wanted to hardcoded in the service. But how can I hardcoded it in the template ? I place all my title in different div and I active the good one when I change page ? – Maximilien Faure Jul 10 '19 at 15:30
  • There are certainly some ways to go. I edited my answer to show you one possibility, i hope that works for you :) – sevic Jul 10 '19 at 21:10
  • It's a solution a little bit cumbersome but it works :) Thanks a lot for your help ;) – Maximilien Faure Jul 11 '19 at 09:09