How to provide an alternate i18n language link in

2019-05-12 18:40发布

问题:

I am currently working on i18n of my Angular app. I use AOT compiling with xlf files to create pre-compiled apps as described here. In the build, I provide a language specific base href (using the --base-href parm). For example, this means, I end up with two language specific apps using the following url paths:

  • /app_path/en/...
  • /app_path/de/...

Now I want to provide a link to the respective alternate language within my app by replacing for example en by de in the active url. I used the Router injection, so I can access its url property, but this property does not give me the full url including the base-href.

How can I find out the base url from within an Angular app?

Alternatively, is there a way to I find out language the app was built for? Can I access the target-language property from the xliff files somehow?

回答1:

When you compile your app for the various languages you set the locale in the ng build process:

./node_modules/.bin/ngc --i18nFile=./locale/messages.es.xlf --locale=es --i18nFormat=xlf

You can get access to this locale by injecting it to your component:

import { Inject, LOCALE_ID } from '@angular/core';
...
constructor(@Inject(LOCALE_ID) locale: string, ...

Then you can use the locale string to determine the current language. In the example above the locale was set to "es"

Hope this helps



回答2:

First, let Angular inject the Router and Location objects (not sure why Router is needed):

constructor(private router: Router, private location: Location) {}

Then, to determine the base path (base href):

let fullpath = this.location.prepareExternalUrl(this.location.path());
let basepath = fullpath.substr(0, fullpath.lastIndexOf(this.location.path().substr(1)));

Finally, this is how you can create a list of alternate language urls (in urls):

const languages = ["en", "de", "fr", "it"];  // List of available languages 
let urls = [];
for (let lang of languages) {
  let url = basepath.replace(/\/(..)\/$/, "/" + lang + "/") + this.location.path().substr(1);
  if (url !== fullpath) {
    urls.push(url);
  }
}

Note that the basepath.replace assumes a two-character language code between slashes. This won't work for something like "en-us" which would require a slightly enhanced regex. I still haven't found a way to identify the language of the currently running app.