Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

ngx-i18nsupport

martinroob56.5kMIT0.17.1

Some tooling to be used with the Angular 2 i18n workflow

i18n, tooling, angular, xliff, xmb

readme

Build Status Dependency Status devDependency Status Code coverage npm

ngx-i18nsupport

Some tooling to be used for Angular i18n workflows.

This page contains just a very short description about the installation process and usage. For details have a look at the Tutorial for using xliffmerge contained in the Wiki pages (recently updated to Angular 6).

There is also some support to use dynamic translations based on ngx-translate in parallel. See details at the Wiki page ngx translate usage

Table of Contents

Introduction

Angular has a specific way of dealing with internationalization (i18n). It is described in the official documentation Angular Cookbook Internationalization (i18n).

Said in one sentence,

  • markup your strings to translate in your templates with an attribute i18n
  • run the Amgular extraction tool (ng-xi18n) to extract the strings in an XML Format called [XLIFF-1.2]
  • copy and then translate the extracted file for every language you plan to support
  • run the ng compiler to generate a special version of your app for the different languages

There is an excellent Blog Article by Phillippe Martin Deploying an i18n Angular app with angular-cli , which describes it in detail.

But there are some maior gaps in the workflow. That´s where this tool comes into play.

First, you have to create a complete translation, otherwise, the ng compiler will not generate a version. It is not possible to run with partial translation.

Second, whenever you change something in your app, you have to regenerate the xliff, but there is no documented way how to merge this with the already existing translated files. There are new translation unit, that you have to merge in, and there are translation units, that do not exist any more.

Installation

npm install -g ngx-i18nsupport

This will install a script called xliffmerge.

You can then integrate the script in your angular i18n workflow, typically in the package.json script section:

"scripts": [
  ...
  "extract-i18n": "ng xi18n --output-path i18n && xliffmerge --profile xliffmerge.json en de"
 ]

Usage

xliffmerge [options] [language*]

Merge translations from a generated master to language specific files

Options:

-p, --profile        <json-configurationfile> read confguration data from profile (see below).
-v, --verbose        activate debug mode (produce more output)
-q, --quiet          quiet mode, only errors and warnings are show
-h, --help           output usage information
-V, --version        output the version number

language is an ISO shortcut for the language(s) you use, e.g. "en", "de", "de-ch", ...

json-configurationfile is a json file containing some configuration values used by xliffmerge. Most times you simply mention it in your npm script using the --profile-option. Instead of having a separate file you can also put the configuration in your package.json. If no profile is given, xliffmerge looks for configuration values in package.json (starting with version 0.14).

The following list shows all allowed content (every value is optional, there is a json schema available too):

{
  "xliffmergeOptions": {
    "srcDir": "i18n",
    "genDir": "i18n",
    "i18nFile": "messages.xlf",
    "i18nBaseFile": "messages",
    "i18nFormat": "xlf",
    "encoding": "UTF-8",
    "defaultLanguage": "en",
    "languages": ["en", "de"],
    "removeUnusedIds": true,
    "supportNgxTranslate": false,
    "ngxTranslateExtractionPattern": "@@|ngx-translate",
    "useSourceAsTarget": true,
    "targetPraefix": "",
    "targetSuffix": "",
    "beautifyOutput": false,
    "allowIdChange": false,
    "autotranslate": false,
    "apikey": "",
    "apikeyfile": "",
    "verbose": false,
    "quiet": false
  }
}

The options are:

  • srcDir (string, default "."): directory, where the master file is expected
  • genDir (string, default "."): directory, where files are written to (normally identical with srcDir)
  • i18nFile (string, default "messages.xlf"): master file (relativ to srcDir)
  • i18nBaseFile (since 0.13) (string, default "messages"): base name of master file (without suffix) (relativ to srcDir). Only used if i18nFile is not set. Useful to generate different filename for different projects. E.g. i18bBaseFile: project1messages produces language files project1messages.de.xlf ...
  • i18nFormat (string, default "xlf"): xlf for XLIFF 1.2 or xlf2 for XLIFF 2.0 or xmb for XML Message Bundles
  • encoding (string, default "UTF-8"): expected encoding of xlf, xlf2 or xmb files
  • defaultLanguage (string, default "en"): the native language used in your templates
  • languages (array of strings): list of languages (if not spefified at command line)
  • removeUnusedIds (boolean, default true): flag, if unused IDs should be removed during merge
  • supportNgxTranslate (boolean, default false): flag to active json translation files for ngx-translate
  • ngxTranslateExtractionPattern (string, default @@|ngx-translate): defines what messages are exported to json translation files for ngx-translate. For details how to use it have a look at the Wiki Page ngx translate usage.
  • useSourceAsTarget (boolean, default true): flag, if source should be copied to target for new trans-units
  • targetPraefix (since 0.12.0) (string, default """): when the flag useSourceAsTarget is set and a source is copied to target, then the target string will be praefixed by this value. E.g. targetPraefix: "%%" and source contains the string "menu", target will contain "%%menu" at the end.
  • targetSuffix (since 0.12.0) (string, default """): when the flag useSourceAsTarget is set and a source is copied to target, then the target string will be suffixed by this value. E.g. targetSuffix: "%%" and source contains the string "menu", target will contain "menu%%" at the end.
  • beautifyOutput (since 0.16.0) (boolean, default false): when set to true, the generated xml output will be send through a beautifier (pretty-data) to get consistent output. See (xliffmerge #64 Could xlf output be better formatted) for details.
  • allowIdChange (since 0.11.0) (boolean, default false): flag, wether xliffmerge should merge transunits with changed IDs. When there is only a small change in the original message text, e.g. a trailing white space, the Angular extraction tool will change the ID of the unit. This means that the translations of the unit are lost. When you activate this flag, xliffmerge will check for units with only white space changes and merge them correctly.
  • autotranslate (since v0.7.0) (boolean or array of strings, default false): flag, if new units should be automatically translated by Google Translate. You can also specify a string array with the languages you want to auto translate (e.g "autotranslate": ["fr", "ru"]). For details how to use it have a look at the Wiki Page xliffmerge-autotranslate-feature.
  • apikey (since v0.7.0) (string, default ""): API key for usage of Google Translate. This or apikeyfile or env var API_KEY_FILE must be set if you activate autotranslate by setting autotranslate.
  • apikeyfile (since v0.7.1) (string, default ""): file that contains API key for usage of Google Translate. This or apikey or env var API_KEY_FILE must be set if you activate autotranslate by setting autotranslate.
  • verbose (boolean, default false): controls output
  • quiet (boolean, default false): controls output

Generate (untranslated) language files, if not already there

When you run xliffmerge, it will read the master xliff file messages.xlf. This is the file generated by the Angular extraction tool ng-xi18n.

Then for every language you specified, it will create a new language specific file, e.g messages.en.xlf or messages.en.xlf.

These files are mainly copies of the master, but they contain the target translations for all translation units of the master.

If the master contains

  <trans-unit id="xy...">
    <source>Hello, world</source>
  </trans-unit>

then the generated file for English (messages.en.xlf) will contain

  <trans-unit id="xy...">
    <source>Hello, world</source>
    <target state="final">Hello, world</target>
  </trans-unit>

and the generated file for German (messages.de.xlf) will contain

  <translation-unit>
    <source id="xy..">Hello, world</source>
    <target state="new">Hello, world</target>
  </translation-unit>

Obviously this is not the correct translation, it is just no translation. This is shown by the state new. The next step you have to do is to translate the file (or to let it translate). Depending on the software you use for translation you can filter for that state new.

Have a look at my sister project TinyTranslator. It can filter for new untranslated entries and allows to edit xlf file very easily.

The file for English on the other hand is correct. So, due to the fact, that English is the default language here, the state is translated.

The Angular compiler can now use both files to generate language specific versions.

Merge new translation units into the existing language files

Generating translation files for each language and translating them is just the beginning.

When you continue developing your app, you will make changes on the existing templates, add new one, etc.

Now, when you are ready to publish a new release, you will run the ng-xi18n tool again and it will create a new messages.xlf for you. There will be new trans-units in it, and there will be trans-units, that are now removed from the file.

But what do you do with your existing translation for the old version of your app? You don`t want to restart translating the whole stuff.

xliffmerge can do it for you. It will merge the newly created messages.xlf into your existing language specific files.

Whenever it finds an ID in messages.xlf, that does not exist in the language file, it will create it with a dummy translation and mark it as new, just the same way, that happens when creating a new language file.

Whenever it finds the ID in the language file, it will not touch it, so you will not lose the translation.

And whenever it finds an ID in the language file, that does not exist in the messages.xlf anymore, it will remove it from the language file (you can prevent that by setting removeUnusedIds to falsein the profile).

So after running it, you just have to translate the new parts.

Once again: TinyTranslator might help you to do that.

Tests

npm test

This will run a testsuite that checks all relevant aspects of xliffmerge.

Contributing

I did not really think about contributions, because it is just a small experimental project.

But if you are interesting, send me an email, so that we can discuss it.

References

changelog

0.17.1 (2018-09-21)

Bug fixes

  • xmb/xtb format Optionally do not merge source value into new translation unit value (leave blank). (#103). Flag useSourceAsTarget now works correct for xmb/xtb format.

0.17.0 (2018-08-07)

Bug fixes

  • xliffmerge wrong empty lines were added when using beautifier. (#96). The beautifier is totally changed, so this might result in slightly changed outputs.

Features

  • xliffmerge Preserve order for newly added units. (#96). When merging new units from master to translation file the new units are now inserted at the same position as they were in the master.

0.16.3 (2018-07-12)

Bug fixes

  • autotranslate HTML encoding is re-encoded - results in HTML encoding being output as text. (#94). Issue is caused due to the fact that google translate returns &#36; instead of apostrophe. The lib expects "normal utf8 strings" as translation. Now the returned translation will be decoded using library he.

0.16.2 (2018-06-01)

Bug fixes

  • xliff 1.2 format: Invalid order of target element in xlf12. (#90)

0.16.1 (2018-05-25)

Bug fixes

  • xliffmerge: New configuration flag beautifyOutput now working. When set to true now pretty-data (the library beyond pretty-xml) will be used to format the output. (#64) (#88)

0.16.0 (2018-05-01)

Bug fixes

  • xliffmerge xliffmerge fails when ICU message contains interpolation and/or tags (#83).

  • xliffmerge Placeholder index is invalid (#84).

Features

  • xliffmerge: There is a new configuration flag beautifyOutput. When set to true now pretty-data (the library beyond pretty-xml) will be used to format the output. (#64)

0.15.0 (2018-04-22)

Bug fixes

  • xliffmerge Merge for source language isn't updating (#81). This happened when there was an explicitly set ID and the original text was changed.

0.14.0 (2018-04-16)

Features

  • xliffmerge: Allow configuration to be part of package.json (#72). You can now put your configuration to the package.json instead of having it in a separate file. There is also a JSON schema file available to check the configuration values (node_modules/ngx-i18nsupport/dist/xliffmerge/configuration-schema.json, actual version available under configuration-schema.json).

Bug fixes

  • autotranslate Error Auto translation from "en" to "de" failed: "Invalid request: Required Text" is fixed (#78). This error occured when autotranslation was enable and there were no units to translate (because they are already translated).

0.13.0 (2018-03-19)

Features

  • xliffmerge: Added ability to change i18n basename to something other then 'messages' (#74). There is a new option i18nBaseFile. This was a contribution of rwlogel.

0.12.0 (2018-02-23)

Features

  • xliffmerge: Added support to add a prefix to translated target languages.
    There are 2 new options targetPraefix and targetSuffix used for copied untranslated units (#70).

0.11.1 (2018-02-16)

Bug Fixes

  • xliffmerge: fixed bug with "allowIdChange: true", it changes "new" to "translated" (#68).

0.11.0 (2018-02-02)

Features

  • xliffmerge: Added new option "allowIdChange" (#65). When there is only a small change in the original message text, e.g. a trailing white space, the Angular extraction tool will change the ID of the unit. This means that the translations of the unit are lost. When you activate this flag, xliffmerge will check for units with only white space changes and merge them correctly. This was a contribution of Szpadel.

Bug Fixes

  • xliffmerge: fixed xliffmerge removes trailing line break when there is an update (#66).

0.10.0 (2018-01-12)

Features

  • ngx-translate: You can now specify in detail what entries are exported to ngx-translate, you can supress exporting all entries with explicitely set IDs (#62). For details how to use it have a look at the Wiki Page ngx translate usage.

  • xliffmerge: Technology update to typescript 2.6 and latest versions of all used dependencies.

0.9.0 (2017-11-06)

Features

  • xliffmerge: support for 'en_US' language format (_ is now allowed in language codes) (#59). This was a contribution of kennanseno.

Bug Fixes

  • xliffmerge: fixed travis build failure due to changed definition files of chalk library (upgraded chalk to 2.3)

0.8.8 (2017-10-19)

Bug Fixes

  • xliffmerge: xliffmerge uses wrong state values for new XLIFF 2.0 segments (#57).

0.8.6 (2017-09-25)

Bug Fixes

  • xliffmerge: correction for setting boolean parameters (removeUnusedIds, supportNgxTranslate)(#55). This was a contribution of vhdirk.

0.8.5 (2017-08-29)

Bug Fixes

  • autotranslate: Autotranslate parameter is checked against first given language instead of default language (#52).

0.8.4 (2017-08-22)

Bug Fixes

  • xliffmerge: When autotranslate is disabled, there should be no warning "Auto translation from..." (#49).

0.8.3 (2017-08-18)

Features

  • xliffmerge: Merge source content if id is explicitly set and source is changed. (#46).

Bug Fixes

  • xliffmerge: handle ICU equiv in XLIFF 2.0 (#47).

0.8.0 (2017-08-11)

Features

  • xliffmerge: merging updated description and meaning (#44).

0.7.4 (2017-07-09)

Bug Fixes

  • xliffmerge: runtime error map is not a function when using autotranslate v0.7.2 (#40). This is the next serious bug. Second try to fix it. Do not use v0.7.3 too.

0.7.3 (2017-07-09)

Bug Fixes

  • xliffmerge: runtime error map is not a function when using autotranslate v0.7.2 (#40). This is the next serious bug. Do not use v0.7.2 too.

0.7.2 (2017-07-09)

Bug Fixes

  • xliffmerge: run with version 0.7.1 breaks with an exception: (#38). This is a serious bug. Do not use v0.7.1.

0.7.1 (2017-07-07)

Bug Fixes

  • build process: Travis CI build green again (broken due to problem with Typescript 2.4.1: #17630 @types/request. Temporary fixed by pinning Typescript to 2.3.1.

Features

  • autotranslate: API Key can now be read from file instead of setting it explicitly. Key is not shown in debug output any more. (#35). For details how to use it have a look at the Wiki Page xliffmerge-autotranslate-feature.

0.7.0 (2017-07-07)

Features

0.6.2 (2017-06-02)

Bug Fixes

  • xliffmerge: Improve error messages (#31).

  • xliffmerge: problems with parsing messages that contain same tag multiple times (lib #26).

0.6.1 (2017-05-26)

Bug Fixes

  • xliffmerge: xlifffmerge emits wrong message 'WARNING: transferred 28 source references from master to "de" for format xtb' (#28).

0.6.0 (2017-05-25)

Bug Fixes

  • xliffmerge: Format xmb should create xtb files for translations. (#25). There is no migration tooling, so if you do have translated xmb files, you must manually correct them to xtb.

  • xliffmerge: File suffix change. For format XLIFF 2.0 the suffix of the generated files is xlf now (was xlf2, which is not correct). If you already have such files, you should rename them before running xliffmerge. Otherwise they will not be merged.

Features

  • xliffmerge: xliffmerge does not merge the new source references. (#24)

  • xliffmerge: For format XLIFF 2.0 source references are supported now.

0.5.0 (2017-05-05)

Features

  • xliffmerge: added XLIFF 2.0 support. (#20)

0.4.0 (2017-05-03)

Bug Fixes

  • xliffmerge: xliffmerge creates empty json files (#18)

Features

  • xliffmerge: create an API to access parsing functionality. (#11). The API is in a separate npm package ngx-i18nsupport-lib.

  • xliffmerge: use explicitly set IDs for ngx-translate data generation. (#15) For detail have a look at the Wiki page ngx translate usage.

  • xliffmerge: Handle new source element introduced with Angular 4. (#21)

0.3.1 (2017-04-25)

Bug Fixes

  • xliffmerge: compilation problem in WriterToString (#19)

0.3.0 (2017-04-24)

Features

  • xliffmerge: Added useSourceAsTargetOption, allows empty translations if set to false.

0.2.1 (2017-03-27)

Bug Fixes

  • xliffmerge: Wrong line endings in bin (#12)

0.2.0 (2017-03-17)

Bug Fixes

  • xliffmerge: Wrong version displayed (#2) (second try to fix it)
  • xliffmerge: Code coverage display is too low (#8)

Features

  • xliffmerge: Added support for placeholders, linebreaks, embedded html (#9)
  • xliffmerge: Added support for ngx-translate (#5)
  • documentation: added ngx-translate integration page (as part of the wiki) (#5)

0.1.0 (2017-03-10)

Bug Fixes

  • xliffmerge: Wrong version displayed (#2)

Features

  • xliffmerge: Added support for xmb format (#4)
  • xliffmerge: languages can now be specified in the profile (#6)
  • documentation: added Usage Tutorial (as part of the wiki) (#3)
  • documentation: added this Changelog.md

0.0.4 (2017-02-28)

Bug Fixes

  • xliffmerge: missing .npmignore prevents starting (#1)

0.0.3 (2017-02-24)

Initial version