1
votes

I'm a great fan of the i18n process shipped with Angular 2+, in particular the following two features:

  1. The ability to generate translation files out of annotated HTML templates using a CLI command (ng xi18n).
  2. The ability to replace template texts with their translations at build time (saving up resources at runtime).

Now I'm working on a non-Angular project and would like to implement an i18n process similar to the one described above. The project is based on AngularJS and uses custom Webpack bundling. HTML template files are currently loaded with Webpacks raw loader and bundled as strings.

Webpack itself suggests concatenating its HTML and i18n loaders. While this would probably solve (2), it doesn't tackle (1) and the syntax required in the templates would be pretty far away from the one used in Angular (i.e. adding i18n="" attributes to elements that have to be translated).

Does anyone have experience with this kind of problem? Is there a way to use a specialised Webpack loader for this use case or maybe even a tiny part of the Angular 2+ build system?

1

1 Answers

0
votes

I have experiences to implement use case like this. You need to write service to read the config file contain the xml translate then inject it in main.ts at bootstrap phase of your app so it can read the xml translation

main.ts

        import { platformBrowserDynamic }  from '@angular/platform-browser-dynamic';
        import { getTranslationProviders } from './app/i18n-providers';

        import { AppModule } from './app/app.module';

        getTranslationProviders().then(providers => {
          const options = { providers };
          platformBrowserDynamic().bootstrapModule(AppModule, options);
        });

i18n-providers.ts

    import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID } from '@angular/core';

    export function getTranslationProviders(): Promise<Object[]> {

      // Get the locale id from the global
      const locale = document['locale'] as string;

      // return no providers if fail to get translation file for locale
      const noProviders: Object[] = [];

      // No locale or U.S. English: no translation providers
      if (!locale || locale === 'en-US') {
        return Promise.resolve(noProviders);
      }

      // Ex: 'locale/messages.es.xlf`
      const translationFile = `./locale/messages.${locale}.xlf`;

      return getTranslationsWithSystemJs(translationFile)
        .then( (translations: string ) => [
          { provide: TRANSLATIONS, useValue: translations },
          { provide: TRANSLATIONS_FORMAT, useValue: 'xlf' },
          { provide: LOCALE_ID, useValue: locale }
        ])
        .catch(() => noProviders); // ignore if file not found
    }

    declare var System: any;

    function getTranslationsWithSystemJs(file: string) {
      return System.import(file + '!text'); // relies on text plugin
    }

then in your html

    <h1 i18n="User welcome|An introduction header for this sample">Hello i18n!</h1>