2

We are writing a website in Angular 6, using Visual Studio Code. The website will be translated to several languages but for now we are keeping it to Swedish and English with English as the default language. We extract the strings from the HTML-files using the xi18n command and we use the ngx-extractor command from i18n-polyfill to extract the strings from the typescript files.

My problem is that I want to do the translation as a natural step during coding and not add it at the end of the project as an afterthought. I want to update the translation files with both HTML and typescript strings at the same time. While I can do this for the HTML files with the help of xliff the command I use remove the typescript strings the next time I run it.

My commands as declared in package.json:

"scripts": {
        "i18n-extract": "ng xi18n --output-path=locale --out-file messages.xlf --i18n-locale en && xliffmerge",
        "ngx-extract": "ngx-extractor -i ./src/**/*.ts -f xlf -o ./src/locale/messages.xlf --i18n-locale en && xliffmerge"
    },
    "xliffmergeOptions": {
        "srcDir": "src/locale",
        "genDir": "src/locale",
        "i18nFile": "messages.xlf",
        "i18nBaseFile": "messages",
        "encoding": "UTF-8",
        "defaultLanguage": "en",
        "languages": [
            "sv",
            "en"
        ],
        "removeUnusedIds": true,
        "supportNgxTranslate": false,
        "ngxTranslateExtractionPattern": "@@|ngx-translate",
        "useSourceAsTarget": true,
        "targetPraefix": "",
        "targetSuffix": "",
        "beautifyOutput": false,
        "allowIdChange": false,
        "autotranslate": false,
        "apikey": "",
        "apikeyfile": "",
        "verbose": true,
        "quiet": false
    },

If I do npm run i18n-extract I get three files: messages.xlf, messages.en.xlf, messages.sv.xlf. If I then do npm run ngx-extract the three files are updated with the typescript strings at the end. When I do npm run i18n-extract again after that, all typescript strings are removed from messages*.xlf since i18n and xliffmerge thinks that what really are typescript strings are HTML strings that have been removed from the HTML code. My workaround right now is extracting the typescript strings to another file (messages.ts.xlf) but that only produces the generic file. I copy the code to messages_ts.en.xlf and messages_ts.sv.xlf and add <target> tags to all <trans-unit> tags and then copy that to the messages.en.xlf and messages.sv.xlf files. This is really tedious.

Question: How do I continuously extract strings from HTML and typescript files for translation? Is there a way to run the xi18n and ngx-extractor commands first and then merge them with xliff? Preferably on one command line I can add to the scripts section in packages.json to lessen the risk of missing any of the steps.

I just cannot find anything in the i18n cookbook or the polyfill readme that helps. This is what I found here on Stack Overflow:

Updates to i18n translation files in Angular disusses the xliff command, but I already knew everything in that article.

angular-i18n Angular 6 Internationalisation : How to deal with variables gives excellent help about ngx-extractor but not how you merge several languages continuously.

komron
  • 2,267
  • 2
  • 17
  • 26
Katja
  • 21
  • 4

1 Answers1

0

You can use the tool xliffmerge it comes with this package.

We are using the following command:

# Generate the xliff files from html
ng xi18n --i18nFormat xlf --output-path i18n --i18n-locale en 

# Update the generated xliff files with translations from typescript
&& ngx-extractor --input src/**/*.ts --format xlf --outFile src/i18n/messages.xlf 

# OPTIONAL: We remove the context as it clutters the file and brings no benefits for us. Have a look to the linked script
&& node src/i18n/remove-context.js src/i18n/messages.xlf 

# Merge the newly generated file with the existing translation files.
&& xliffmerge --profile xliffmerge.json`

Our xliffmerge configuration looks like this:

{
  "xliffmergeOptions": {
    "srcDir": "src/i18n",
    "genDir": "src/i18n",
    "defaultLanguage": "en",
    "languages": [
      "en",
      "de"
    ]
  }
}

You can see it in action here

Daniel Habenicht
  • 2,133
  • 1
  • 15
  • 36