Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I reuse i18n translation keys in Angular?

I'm using the i18n support for Angular2 (4.0.3) as documented here. I've generated the xlf files and everything is working happily.

However, let's say that I have a menu button that links to my home page. I create the DOM node using the attribute i18n="@@homeTitle". Now, in my home page component, I'd like to use the same translation ID in my <h1> tag, so that I get the same translation without having to maintain multiple entries with the same content in the xlf files.

I had hoped to do something like the below, and have it auto-populate my <a> node with the appropriate translation.

// home.component.html
<h1 i18n="@@homeTitle">Home</h1>

// menu.component.html
<a routerLink="/" i18n="@@homeTitle"></a>

However, this does not work. The <a> node shows up with empty text, not the translation target. (Further, by default there is no translation target in the auto-generated messages.xlf file.)

The docs actually call out this situation but do not offer a solution. The issue was also called out by a user on GitHub for common strings like Monday and cancel, but that issue thread does not cover a solution to this particular problem.

How can I reuse i18n translations defined in my xlf files across multiple nodes?

Edit: Here is the xlf generated by using ng-xi18n --i18nFormat=xlf:

<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
  <file source-language="en" datatype="plaintext" original="ng2.template">
    <body>
      <trans-unit id="homeTitle" datatype="html">
        <source>Home</source>
        <target/>
      </trans-unit>
    </body>
  </file>
</xliff>

If the parsing order of the two @@homeTitle nodes is switched, <source> changes respectively.

like image 270
Cat Avatar asked Aug 16 '17 21:08

Cat


People also ask

What is extract-i18n in Angular?

1. Angular CLI provides extract-i18n command to extract the marked text in the component into a source language file. 2. The extract-i18n command is run from project root directory as following. ng extract-i18n.

What is $localize in Angular?

Angular Internationalizationlink Localization is the process of building versions of your project for different locales. The localization process includes the following actions. Extract text for translation into different languages. Format data for a specific locale.


1 Answers

TLDR; Just don't worry about custom IDs and write your strings correctly. The ng xi18n tool will take care of matching the identical strings under a single <trans-unit>. Your translations will then be applied to the whole unit.

The longer explanation: The xi18n tool matches strings in your app by string equality. Whenever it finds a new string, it compares it to the already found ones. If there is an exact match, it includes the new string in an existing <trans-unit>. If there is not, it creates a new one and generates a new ID.

This behaviour, however, can be changed by using custom IDs and translation hints. If a new string is found and contains a custom ID, the current messages will be checked for this particular ID and assigned to an existing <trans-group>, if found. Note, that this process disregards the string itself, so any non-empty value will be merged into the found <trans-group> with the custom ID. Empty strings are omitted.

As the documentation mentions, only the first element with custom ID will be inspected for the source string. When there is a second element with the same ID, it's string value will not be parsed. This means that you could alter your solution to have all the other nodes with your custom ID contain a placeholder string. The localization would then work as you expect.

// home.component.html
<h1 i18n="@@homeTitle">Home</h1>
// menu.component.html
<a routerLink="/" i18n="@@homeTitle">ANY PLACEHOLDER STRING YOU WANT</a>

As you might see, this doesn't look particularly fancy. Moreover, you have to remember the custom ID for further re-use. I'd suggest not doing that, unless absolutely necessary. In my opinion, it is easier to just write the string (in your case "Home"), slap an i18n attribute onto the element and don't worry about re-use, since it will be done automatically. I'd use custom IDs mainly in case you need to have multiple varying (contextual) translations of one string.

like image 129
Heehaaw Avatar answered Oct 04 '22 11:10

Heehaaw