Skip to content

Tutorial for using xliffmerge with angular cli

Martin Roob edited this page Mar 6, 2017 · 25 revisions

WORK IN PROGRESS

Just started writing, will delete this lines when finished.

Start a new project

If you haven't done it at all, install angular-cli globally:

npm install -f @angular/angular-cli@latest

Then you can create a new project:

ng new sampleapp

cd sampleapp

Change the app, so that it uses some texts that need translations

For this tutorial we assume, that your preferred language is not English, but something else, e.g. German. So what you want to write your application in German and translate it to English later.

So as a first step we change our application to German and additionally mark all text, that needs translation, with an i18n-Attribute (for details have a look at the Angular Cookbook about Internationalization).

Our application.html now looks like this:

<h1 i18n>Meine erste I18N-Anwendung</h1>
<p i18n>Anwendung läuft!</p>

Try running it (ng serve or npm run start), fix the test cases, if you want (they test for 'app works!' and will fail after the change).

Generate a messages.xlf file

After the changes made, the application now contains some i18n marked stuff and so you can extract this stuff for translation. angular-cli has a task for this (since 1.0.0-rc-0, i guess), so you can just type

ng xi18n --output-path src/i18n --locale de

Instead of typing, it is better to add a script to your package.json, that does it for you. Then you don't have to remember the command to type. So just add the following to your package.json scripts section:

{
  [...]
  "scripts": {
    [...]
    "extract-i18n": "ng xi18n --output-path src/i18n --locale de"
  }
  [...]
}

and then you can type

npm run extract-i18n

Some words about the parameters used in the command.

--output-path spefifies the path, where the generated file will be saved. We prefer to have it under src/i18n.

--locale specifies the language, that is used in the templates (the default language). It is supported starting with Angular 4. In prior versions it is ignored and the generator always assumes your templates are written in English.

Now you will find a file src/i18n/messages.xlf. If you open it with an editor, you will see, that it is an XML file containing

      <trans-unit id="18c6a843a0bb6b8756fad2802e65443e7d316409" datatype="html">
        <source>Meine erste I18N-Anwendung</source>
        <target/>
      </trans-unit>
      <trans-unit id="6ef3aa3d7b8cfb612bc43a6166ec9b64e442a8c2" datatype="html">
        <source>Anwendung läuft!</source>
        <target/>
      </trans-unit>

In the next step you have to create a copy of this file for every language, you want to support, and you have to translate it.

This is, where xliffmerge comes into play.

Generate language files

Change the script you added in the last section to your package.json:

{
  [...]
  "scripts": {
    [...]
    "extract-i18n": "ng xi18n --output-path src/i18n --locale de && xliffmerge --p xliffmerge.json de en"
  }
  [...]
}

xliffmerge.json is a small configuration file, create it with the following content to tell xliffmerge where the files are located.

{
  "xliffmergeOptions": {
    "srcDir": "src/i18n",
    "genDir": "src/i18n"
  }
}

Now run the extraction process once again (npm run extract-i18n).

Now you will find 3 files under src/i18n

  1. messages.xlf the master file containing all the messages found in your app.
  2. messages.de.xlf the German version
  3. messages.en.xlf the (up to now untranslated) English version.

If you open the files with a text editor, you will see

  • messages.xlf is, what angular created for you, the <target/> elements are empty (no translation), the attribute sourceLanguage="de" was corrected by xliffmerge.
  • messages.de.xlf contains a copy, but the <target> elements contain the same values as the source elements. There is an additional attribute state="final".
  • messages.en.xlf is nearly the same, but the targetLanguage is set to "en" and all <target> elements have an attribute state="new". This marks the fact, that you have to translate it by your own.

Run your English version of the app