Vendure: Admin UI locale setting & data

Created on 20 Nov 2020  路  7Comments  路  Source: vendure-ecommerce/vendure

Describe the bug
locale
Admin UI app doesn't change the locale settings according to the language set. Results in US datetime formatting everywhere, including datepickers. As well as currency and thousand and decimal separators. (e.g. in Europe currency comes after value) and for central europe decimal _comma_ is used instead of _dot_, thousands are separated by space.

Expected behavior
App should switch to locale according set language and registerLocaleData() to load formats accordingly.

Environment (please complete the following information):

  • @vendure/core version: v0.17.0

Possibility of changing date representation for "Updated at"

This is feat request: Having an option to change relative date representation - _X minutes ago_ format to standard absolute date representation - _dd.mm.yy hh:mm:ss_ (as locale format), or at least having absolute date representation if change is older than an hour/day (and in such case the tooltip on mouseover showing absolute representation would be nice addon).
... _53 days ago_ does more harm than help.

bug 馃悰

All 7 comments

Wow this turns out to be surprisingly more complicated to fix than I thought. In Angular, the LOCALE_ID token is specified at build-time and the locale data is then compiled into the app bundle. I don't think we want to load all locales by default, since that might make the bundle huge.

Example: this article explains how to create your own custom date pipe which wraps Angular's formatDate function, but still requires you to register the desired locales statically.

As far as I understand, all that locale formatting data should be already included in the browser's Intl object (e.g. the Intl.NumberFormat() method). So maybe the solution is to not use Angular's pipes at all and implement our own pipes for date, number and currency which wrap the Intl APIs.

Context re Intl API & Angular

Back in August 2016, Angular _was_ using the built-in Intl API for date/number formatting, but there were lots of compatibility issues as discussed in this GH issue: [Disscussion] Internationalization API issues.

As a result the Intl dependency was removed in favour of a custom implementation, which is what we have today - see commit feat(common): drop use of the Intl API to improve browser support

And looking at caniuse data, it looks like back in 2016 support was indeed an issue (which is why Angular shipped with an Intl polyfill at the time. Now in 2021 things look better.

I will investigate further the idea of replacing the built-in Angular pipes with custom versions based on Intl.

I believe this is not really an issue in native Angular i18n implementation as it have "build" per each language and is the reason why they didn't pursue it further.
Note to say in Angular10 there was huge advancement in their i18n that brought $localize (localization in TS files which was the biggest lack prior) and reducing build times (prior there was a need for building per locale, today it just builds once and replaces strings through $localize function).
For what I know this native i18n is more performant as all app strings doesn't have to be in memory (as is the case of ngx-translate) also the default language have better fallback behavior (showing strings of default language rather than string identifiers.
I'm using it without lacking any features few months now.

So maybe this is the point to evaluate effort of creation of custom locale pipes and redoing the i18n system to the native one + evaluate the effort making it work with extensions.

I just read through the whole guide at https://angular.io/guide/i18n.

I've not looked at it for a while, and indeed the i18n story is _way_ better now than last time I checked.

In particular, the support of the ICU format is a must, which they didn't have before.

I might have missed it, but I didn't see an example of localizing text inside a TS component file. Do you have any example or can you point to a doc showing how this works?

Also, how is it to work with the XLIFF format? I'm slightly scared of the XMLishness. Do you use an editor or edit the raw files?

I'm warming to the idea of just migrating over to native i18n, but if so I'll postpone it from this next patch release, as there will be breaking changes to the extensions API. I'll also need to figure out how we even do extensions with translations.

Yes, the ICU works great in html template, in TS file I had to make my own conditioned transform function that uses $localize (though most of ICU I needed only in html).

The official documentation is quite behind on _$localize_ function.
But it's quite straightforward, you can use it like this const somestring = $localize`:@@optionalId:String that will be extracted to xliff`; (make sure u have installed @angular/localize, using of backtick ` is a must, ' " don't work)
Source comments: https://github.com/angular/angular/blob/master/packages/localize/init/index.ts
Short official introduction is here https://blog.angular.io/angular-localization-with-ivy-4d8becefb6aa
Some additional usecases (with str comment/meaning): https://www.soluling.com/Help/Angular/Index.htm
Basically with that function you can localize any string in TS, I was even able to localize routes as well.

I also like how easy it is to translate any attributes in html like placeholders, image alt's etc.

For generation of XLIFF files and merging current versions with newly extracted strings I use xliffmerge, part of @ngx-i18nsupport. And then for translating the files I use freeware Poedit. The UX of translating is great, you have highlighted untranslated strings, comments, warnings for double/missing spaces etc. And it's a industry standard, even non-techy users were able to translate my files, which would be impossible with JSON.

For example BeerInCans.com is localized with this native i18n - the biggest challenge was making it work together with SSR, but it is not needed for AdminUI. Though I can provide source and assistance for all I've encountered.

Another point to extend the story are locale date ranges - for example current range of a week on the dashboard widget starts with Sunday (US, Canada), in most of countries week starts on Monday.

Thanks for the info on native i18n. _Really_ useful!

For now I have successfully created custom pipes using the Intl API which solves the original issue. I'm going to re-visit migrating to native i18n after v1.0. For now ngx-translate works OK.

Just small refinement to the commit dd0e73a if possible. Change to 24hr vs 12hr time format based on locale settings. For exampel in Czechia only the 24-hour format is used, now it renders time format with AM/PM convention.

21. 3. 2021 4:32:24 odp.
where odp. stands for PM, but it's not used this way here.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Zyles picture Zyles  路  8Comments

michaelbromley picture michaelbromley  路  3Comments

michaelbromley picture michaelbromley  路  6Comments

hendrik-advantitge picture hendrik-advantitge  路  6Comments

michaelbromley picture michaelbromley  路  3Comments