angular / angular

Deliver web apps with confidence 🚀
https://angular.dev
MIT License
94.59k stars 24.64k forks source link

[i18n] plans #16477

Closed ocombe closed 4 years ago

ocombe commented 7 years ago

Here is the list of features / fixes planned for i18n.

If you want new i18n features to be added to Angular, don't hesitate to ask below and I'll let you know if that's feasible and if you should open an issue for it. If you have a bug, open an issue (no need to discuss about it here).

For Ivy

Note: runtime translations and most of the new features will only be available with ivy

Features

Not prioritized

Features

jlutz777 commented 6 years ago

I would like to see the ability to do dynamic bindings in aot mode. There are two use cases in particular to back up why this should be added to the roadmap.

The first is the basic use case where you don't want separate applications for every language. This requires some sort of redirect logic outside the app and doesn't allow dynamic changing of the language without a complete reload of the site.

The second is the case where you are embedding the app in mobile using cordova. As far as I know your choice is to jit, thus slowing down the site, creating a separate app for every language, or including every language in the app (which of course bloats it). None of these are good options. It seems Ionic doesn't use i18n, and I wonder if this is the reason why.

ocombe commented 6 years ago

@jlutz777 those are 2 valid use case, this subject has been discussed internally lately and I've been advocating for that too. It is not easily possible yet given how i18n and AoT work in Angular, but it might be in the future once we get the new compilation process for AoT in v5. I'll add it to the roadmap once/if we have something official and concrete about it.

vishalbhardwaj26 commented 6 years ago

I am working on Electron + Angular 2 app and now trying to add support for Localization for multiple langauge using i18n feature with Angular. Actually extraction of template-string and converting them in different language file formats are clearly documented, though I am still not able to much clear about and looking for:

ocombe commented 6 years ago

Points 2 and 3 will be resolved with the feature "Use translation strings outside of a template - #11405". For the point 1 see the answer I gave to @jlutz777 above. For now you still have to build the app in multiple languages, or use JIT which can dynamically load translations at bootstrap (it's not switching at runtime, but it's still better than having to bundle it x times).

figuerres commented 6 years ago

the UI language used in an application should be something that does not require building multiple versions of the same application. this should not in any way be a "compiler" issue. if it is then the compiler is flawed. the issues should be one of making the application design such that the text can be loaded from a data file at run time. that should be done with a module / library that can be loaded and used like any other. do not make that a compiler function at all.

ocombe commented 6 years ago

@figuerres it's something that will be changed in the future, no promises yet but we are aware of this issue and we are looking at possible solutions, using an external file is one of them

rjcorwin commented 6 years ago

Hi @ocombe - It looks like we're probably going to use i18n in Angular for our application. Are there any features in the docs you think might become deprecated or have breaking changes in the coming months? Any info would be greatly appreciated. And thanks again for the DVD!

ocombe commented 6 years ago

Hey @rjsteinert! Glad to know that! There's only one breaking change planned for now, it's the auto generation of IDs. The method will change and the IDs will not match anymore, but there will be a cli migration tool to update your translation files (and a parameter that you can use to only migrate when you're ready).

actra-gschuster commented 6 years ago

I googled a lot about this topic today and am wondering if there could be a "simple" solution like replacing i18n-tags with a call to a service instead of the translation?

Current: <span i18n>Hello world</span> => rendered to <span>Hello world</span>

My idea: <span i18n>Hello world</span> => rendered to <span>{{i18nservice.translate('pass-in-the-generated-message-id')}}</span>

This way the real translation could be done dynamically in AOT as the service could be filled from an API, file etc. and even switching locales wouldn't be much more than i18nservice.setLocale('de-DE') with loading a new source. Text extraction with xi18n-tool would still work as before and we could leverage the message ids generated anyways to use as index for the translation service. The current implementation would also still work flawlessly as ngc could simply look for a "--use-i18nservice" flag and otherwise compile as until now.

One problem I can currently identify is the injection of the i18nservice into each and every component as it has to exist in the components context to be callable, but that should be solvable in one way or another.

Any thoughts on this?

ocombe commented 6 years ago

It is one of the things that we're considering yes, there's still the problem of how to treat code blocks inside of those translations when the compiler isn't available at runtime (AOT). It would mean that we cannot use angular components/directives/pipes inside of translations...

actra-gschuster commented 6 years ago

Yes, didn't think of that. I'm currently developing a POC/workaround that inlines all translations into the HTML at the build step (webpack), wrapping them into ng-containers with ng-switch. For i18n-attributes it's using a directive setting them on nativeElement. The translations themselves also get "rendered" then to replace all those <x id=".. "/> placeholders.

It's ugly but works...can't wait for ng to support it natively. Will publish the POC later this week, maybe it can be of use for your further conception.

actra-gschuster commented 6 years ago

I came up with a "solution" that suits my needs until there's an implementation. The pre-loader now renders HTML for all locales before handing over to the compiler, works like a charm so far.

Repo: https://github.com/actra-development-oss/ng-i18n-aot-loader NPM: https://www.npmjs.com/package/@actra-development-oss/ng-i18n-aot-loader

figuerres commented 6 years ago

possibly a component could have an attribute that tells the system / compiler that it needs a service. that service then takes and id and a locale and returns the localized text / markup. all the localized text is stored on the server as resources that the service can read from.

if a component does not have the attribute no locale run-time. if the component has it then it call get the localized data at run-time. the compiler just builds the data files and hooks up the service.

this seems to me like a good way to handle the most common need for most applications and not require sites to build and maintain multiple copies of the same app.

actra-gschuster commented 6 years ago

I had that idea, too. Problem is that translations can contain bindings and thus would open the system for code injection when loading translation files from external resources. Additionally, a compiler would be needed to resolve those bindings dynamically depending on the translation.

IMHO a valid solution could be the way I implemented as POC (see comment above) to inline translations at compile time, just in a more elegant, integrated way. Both problems mentioned above would be eliminated, only downside I can imagine is possibly the bundle size, it'd grow to "plain bundle" + (translated html-size locales). That could be lowered by only ng-switching the i18n-tagged html instead of the whole document but still there's a problem for `i18n-`-tags.

figuerres commented 6 years ago

well here is the thing; some times you have limits ....

from a practical stand point it might be better to not have that, you can have a chunk of text that can be given in multiple languages. end of the story.

you need to have a data bound chunk ? ok but that is not inside the internationalized text, it has to be separate. you can still use html and css to style and format the result. but you can't embed or combine them in every way you can think of. like say a div or a p tag can have a number of spans one span is the text and another span is a bound date the text span is bound to the i18n locale service, the date is bound to some date service the two spans are in a paragraph tag that formats them.

Keep it simple, make it work for 95% of all users first then figure out the edge cases.

actra-gschuster commented 6 years ago

I don't see that as an edge case, it's business as usual. Angular is a business-grade framework so many, if not all, of the i18n-users will require bindings, or at least pluralization and selects, inside texts.

<span i18n>Hello, {user.gender, select, m {Mr.}, f {Ms.}} {{user.name}}</span> How would you solve that with separated strings? Simple answer: you can't, as you cannot know the rules of the target language, not every language follows the format 'greeting', 'gender', 'name'.

Separating those chunks would:

The core i18n works in angular as expected and is usable for business-grade apps, the only thing missing apparently is AOT-compatibility, so I don't get your standpoint why a powerful, working system should be replaced by something not half that capable requiring multiple times the work to get it done.

ocombe commented 6 years ago

We have a meeting tomorrow to find a solution to this problem.

figuerres commented 6 years ago

@ocombe glad to hear this, i hope this leads to some good stuff for a future release of Angular , here at work we are really loving how most of it works for our development needs!

SteveRuben commented 6 years ago

@ocombe , is it possible to change language without relaoding the entire document ? I explain : I'm on page named "about" but when I change the language, i'm redirected to main entry page of my application .

actra-gschuster commented 6 years ago

While working on my i18n-app I also came across the known "bug" that external stylesheets from e.g. @angular/material (residing in node_modules) could not be resolved and thus the ng-xi18n-tool failed. I implemented an "ignore missing files"-HostContext for the extraction tool, also as POC but added as PR #17845 to have it linked to the main repo.

@ocombe as you seem to be very active on this topic would you mind having a look at the PR and giving feedback?

ocombe commented 6 years ago

Thanks, I'll take a look at it.

RAJKUMAR-PATTNAIK commented 6 years ago

It's been few days searching a way to implement internalization on whole project including dynamic data, but found nothing concrete. Can you please suggest me something else that at least help me for the time being. Thank you.

jean-philippe-bousselin commented 6 years ago

Hello @ocombe! Can we have a follow up concerning the point raised by @jlutz777 (about dynamic bindings, thus not having one app per language) ?

Thanks a lot for your work!

ocombe commented 6 years ago

@vicb is working on it right now, it'll be in 5.x (not 5.0 but most likely 5.1)

trotyl commented 6 years ago

@ocombe Should the checklist be updated? I can see some of them already been merged in newer versions. And that'll better reflect your hard works. 😃

ocombe commented 6 years ago

yes, good idea, I'll update it edit: updated

Toub commented 6 years ago

Runtime i18n (one bundle for all locales with AOT) - [working on it]

Where is the associated issue / PR / discussion?

dzonatan commented 6 years ago

Would be cool to have an api for extending named date formats (e.g. ultraLongDate) so native date pipe would be aware of it and custom date pipe would not be needed.

chcaru commented 6 years ago

Just curious about progress on "Runtime i18n (one bundle for all locales with AOT)."

My team has multiple large apps with 60+ languages. Right now we run N builds in parallel such that N is the number of languages. This is resource intensive, as you can imagine, especially considering the apps are fairly large and deploy many times a day to multiple environments.

What I'm hoping for is:

  1. Some rough ETA on runtime i18n
  2. Confirmation that runtime i18n will do a single build for all languages
  3. Whether or not each language produced will be lazy loadable or be in a single massive bundle
actra-gschuster commented 6 years ago

@chcaru while waiting for ng to provide a "native" solution have a look at https://github.com/actra-development-oss/ng-i18n-aot-loader/ It provides exactly what you're asking for, one AOT build with multiple locales.

ocombe commented 6 years ago

@chcaru: 1/ rough ETA is Angular v6 (first beta should be by the end of January I believe? not sure), the good news is that code translations should follow quickly after runtime translations since almost all of the work will be done 2/ yes 3/ translations should be separated from the bundle, you'll be able to lazy load the one you need before bootstrap, or just bundle everything in one, we also want to support lazy loading translations for modules, but not sure when it'll be available

Toub commented 6 years ago

@ocombe until angularv6 is released, the most serious option to load translations dynamically and/or create a multi-languages application with a single package is ngx-translate.

Do you have some tips to help people starting using ngx-translate to easily migrate when angularv6 is out? Any bridge between both applications?

ocombe commented 6 years ago

Not really, the code is quite different... we'll see when v6 comes out with those features if I'm motivated to work on a migration tool

rBull commented 6 years ago

Hi, thanks for the transparency of upcoming features.

It would be very helpful to know answers for following questions:

  1. Any idea how different will be the new i18n workflow different from current one described in https://angular.io/guide/i18n ?

  2. Will be the i18n and i18n-* e.g. i18n-title attribute with optional custom id still available in templates?

  3. Will the following commands still work?

    
    ng serve --aot --locale fr

ng xi18n --i18nFormat=xlf ng xi18n --i18nFormat=xlf2 ng xi18n --i18nFormat=xmb



4. how the messages.xlf trans-units extracted from templates will be merged with the ones used in code?
ocombe commented 6 years ago
  1. We will make the update experience as smooth as possible, most likely what worked before will still work after at least until v7.
  2. The i18n attributes will stay the same
  3. the extraction should be the same as well
  4. that's probably the only part that will change, I'm not sure how yet so I prefer not to tell you things that might change, but the messages will be merged at runtime when the views are created (so between bootstrap and the view appearing on the screen)
templth commented 6 years ago

Following the @Toub's comment, for this transition period, we would be interested in having feedbacks for the following approach (mixing i18n attribute and ngx-translate) we want to implement. Our aim is to minimize the more the updates to do in the code when the new i18n support will be ready.

(Note we want dynamic locales, i.e. not one generated app per locale)

Here is a sample:

<!-- Without parameters -->
<div i18n="hello-id" translate>HELLO</div>

<!-- With parameters -->
<div i18n="hello-id" translate [translateParams]="{value: 'world'}">HELLO</div>

Thanks for your feedbacks!

ocombe commented 6 years ago

Could you open an issue on ngx-translate for that? I think that the best thing would probably to update the lib to support "i18n" attributes as an alternative to "translate"

templth commented 6 years ago

@ocombe thanks for the suggestion! Just added an issue for this on ngx-translate...

templth commented 6 years ago

@ocombe the problem I can see is that i18n / i18n-* attributes are removed at runtime (https://github.com/angular/angular/issues/11042). Is there a way to keep them?

ocombe commented 6 years ago

I checked and unless I'm mistaken they are only removed if you use Angular i18n (meaning that you load translations when you're doing the compilation).

templth commented 6 years ago

@ocombe I understand but I don't load the translations since I'm using Angular CLI and started the application with ng serve...

owenmecham commented 6 years ago

@ocombe, our company will soon before an effort to support i18n using the multiple app per locale strategy that is currently prescribed. We're also planning to include the locale in the url and set the base href in the app. Once the runtime i18n feature is complete, what changes would we need to make with our url locale strategy? Is there a better way for us to begin to avoid a large refactor once runtime i18n is released? Thanks for your work on all of this.

owenmecham commented 6 years ago

⬆️ should say "will soon begin"

ocombe commented 6 years ago

one app/locale should still be working as it is right now (minus the small change to load the locale file at bootstrap if you're not using the cli)

elvisbegovic commented 6 years ago

Could someone please target me in which file i18n attributes are removed from template durning bundle ?

cc @ocombe

ocombe commented 6 years ago

It was changed in 4.2.6 (PR https://github.com/angular/angular/issues/17999)

adrm commented 6 years ago

Hi! I've been following this thread for a long time. I saw that the first beta for v6 is out. I read the changelog but did not see anything related to this longstanding issue. Any news on this front? Or at least, is there any guarantee that the interface will be similar to your polyfill?

Thanks for your work!

ocombe commented 6 years ago

It's going to be in one of the last betas, or maybe RC (I know I know...). The interface will be similar to goog.getMsg from closure since that's what google uses internally for code translations: https://developer.pubref.org/static/apidoc/global/closure/goog/getMsg.html But we may be using a wrapper, so maybe it'll change the interface for Angular, not sure yet. In my polyfill I use a similar interface, but with the possibility to define id, description & meaning if necessary, and I believe that we will need that one way or another (either via parameters, or via a decorator)

santhony7 commented 6 years ago

Thanks for all your hard work! We are preparing for a ground-up rewrite of our entire 1.x app starting in April. Is there anything we can/should do to prepare for these changes? Right now we are planning on using 6.x. Thanks again!

chcaru commented 6 years ago

@ocombe Just curious when "Ignore leading and trailing spaces" will land?