Closed kyubisation closed 4 years ago
Another workaround would be to patch the locale data files in node_modules/@angular/common/locales/global/...
as a postinstall step?
The issue is that we have +100 Angular projects at SBB. It would be possible for us to provide a package that patches the locales after installation, but that is a hack and will be met with some resistance from the projects. A cleaner solution would be something I have suggested above.
I agree it would be a hack. It was just another workaround in the meantime.
It is not my place to say, but I think that your proposal is worthy. You would need to ensure that it has the correct format, etc. But I could imagine these "patch" files could be quite small, since you could import the originals and only change the bits you want.
With that in mind, how about a fallback mechanism, where you simply provide a folder to look in first for locale data files? The CLI could then load your files if available, and fallback to the Angular ones otherwise. This would keep your angular.json
file much simpler and avoid the need to keep it in sync with the files in your own locales folder.
Also, in the long run, I would propose that if the CLDR data is wrong then you should be encouraging that project to update its definitions to be correct, since that is where Angular gets its locale data.
I agree it would be a hack. It was just another workaround in the meantime.
I didn't mean to dismiss the workaround suggestion and I will discuss this with my team.
It is not my place to say, but I think that your proposal is worthy. You would need to ensure that it has the correct format, etc. But I could imagine these "patch" files could be quite small, since you could import the originals and only change the bits you want.
With that in mind, how about a fallback mechanism, where you simply provide a folder to look in first for locale data files? The CLI could then load your files if available, and fallback to the Angular ones otherwise. This would keep your
angular.json
file much simpler and avoid the need to keep it in sync with the files in your own locales folder.
That seems reasonable. Should I change my feature request? Or should I directly try to provide a PR?
Also, in the long run, I would propose that if the CLDR data is wrong then you should be encouraging that project to update its definitions to be correct, since that is where Angular gets its locale data.
I tried to explain this in the issue above; apart from the date format in en-CH the date is not per se wrong. And as far as I can tell the CLDR definition is kind of a majority vote with its survey. So changing the data is most likely a complicated process.
I would wait on feedback from the CLI team before modifying your suggestion or attempting an implementation.
@alan-agius4 I just saw that the label "need: further discussion" was added. Does that apply to the Angular CLI team or to me?
@kyubisation, the need further discussion
is used to label issues that need to be discussed further with the rest of team.
@alan-agius4 Has a consensus been reached on this? Would you accept a PR with the fallback design @petebacondarwin mentioned?
Going follow up on this tomorrow, as it looks like we didnβt provide a decision on the implementation details for anyone to pick it up.
@alan-agius4 Can you provide an update?
Hi @kyubisation, @clydin will post an update on what was discussed, since he has more context on this.
The locale data files contained within @angular/common/locales/global
are typically automatically injected into localized applications during the build process. However, the files are also capable of being used directly by importing them into the application code. This usage scenario is typically leveraged when an application requires multiple locales within a single instance. But this usage can also facilitate the augmentation of existing locale data by importing the augmented locale data file immediately before the Angular application is bootstrapped. This would typically be within the main.ts
file of the application. This method has the advantage of allowing changes to the locale data without any additional options.
Please be aware, however, that the contents and format of the locale data files are not considered part of the public API and may change in the future.
If the data for a particular locale is determined to be incorrect, the team recommends attempting to contact the CLDR via the CLDR Survey Tool to propose a set of corrections of the locale data.
A test (via https://github.com/angular/angular-cli/pull/19342) has also been added to the Angular CLI to ensure that this method will continue to function moving forward.
@clydin This does not help at all. Was the conversation between @petebacondarwin and me even read?
Can you elaborate on how this does not help you? The method described allows the en-CH
locale data to be replaced within the application.
How would I do this for 4 different languages in the same build? de-CH, en-CH, fr-CH and it-CH?
If the data for a particular locale is determined to be incorrect, the team recommends attempting to contact the CLDR via the CLDR Survey Tool to propose a set of corrections of the locale data.
As I tried to explain previously, there is no official standard for swiss i18n formats, so the format defined in CLDR seems to be a majority vote.
All the augmentations to the locale data can be put in a single file that is imported into the main.ts
. This also has the advantage of simplifying the setup for each project. Only a single JavaScript import is required to workaround the errant CLDR data as well as centralizing all the augmentations. And when the CLDR data is updated and corrected the import can be dropped.
The augmentations can be setup to be conditionally applied based on the presence of the locale data within the global store. The full locale data also does not need to be replicated; only the changes necessary to correct the locale data. This also provides a long-term sustainment advantage by reducing the risk of changes to the locale data causing breakage (appended additions by newer versions of Angular will be maintained if the data is augmented rather than replaced).
Ok, I think I understand your argument. This would still force us to load all locales for each language bundle. While I understand your reluctance to bake this into the CLI, the approach described by @petebacondarwin does not seem overly complex.
Also see my previous comment in regard to the CLDR.
With this approach all the locales would not necessarily need to be loaded in each bundle (they could be if preferred). As an example, the following would allow augmenting the date format for en-CH
to use dd.MM.y
:
const locales = globalThis.ng.common.locales;
if (locales['en-ch']) {
locales['en-ch'][10][0] = 'dd.MM.y';
}
if (locales['de-ch']) {
...
}
Depending on requirements, additional safety checks could be put in place to cause the application to fail fast if the replaced value is not the expected value; or more complex logic could be introduced to find the value that should be replaced. Though these would mainly be risk mitigations for potential future changes to the structure.
The implementation of the suggested option in itself is not necessarily complex. However, the secondary effects of the introduction of the option do become more complex. Currently, the usage of the locale data files but not the structure are considered part of the public API. By introducing an option that would allow creation and use of custom locale data files, the structure and format would then also become public API. Doing so would require a public API review as well as a design and implementation review of the current structure and its consumers. Changes may need to be made to minimize long-term sustainment costs as well as provide for evolution without excessive breakage. The structure and format would also need to be documented with the potential need for a guide and/or tools to assist in creation and maintenance of the data files. All of this would also need to be sustained throughout the life of the feature. While the described use case is valid, the team felt that at this time the long-term sustainment costs outweighed the inclusion of the discussed option. However, as Angular i18n features and capabilities continue to evolve and expand, this may change in the future.
With this approach all the locales would not necessarily need to be loaded (they could be if preferred). As an example, the following would allow augmenting the date format for
en-CH
to usedd.MM.y
:const locales = globalThis.ng.common.locales; if (locales['en-ch']) { locales['en-ch'][10][0] = 'dd.MM.y'; }
I mistakenly assumed that the CLI used the non global locale variants internally. Yes, this would work for our use case. I apologize for the confusion.
Depending on requirements, additional safety checks could be put in place to cause the application to fail fast if the replaced value is not the expected value; or more complex logic could be introduced to find the value that should be replaced. Though these would mainly be risk mitigations for potential future changes to the structure.
The implementation of the suggested option in itself is not necessarily complex. However, the secondary effects of the introduction of the option do become more complex. Currently, the usage of the locale data files but not the structure are considered part of the public API. By introducing an option that would allow creation and use of custom locale data files, the structure and format would then also become public API. Doing so would require a public API review as well as a design and implementation review of the current structure and its consumers. Changes may need to be made to minimize long-term sustainment costs as well as provide for evolution without excessive breakage. The structure and format would also need to be documented with the potential need for a guide and/or tools to assist in creation and maintenance of the data files. All of this would also need to be sustained throughout the life of the feature. While the described use case is valid, the team felt that at this time the long-term sustainment costs outweighed the inclusion of the discussed option. However, as Angular i18n features and capabilities continue to evolve and expand, this may change in the future.
That is a fair assessment, although disappointing for us.
Thank you very much for the exchange. π
Closing as per above convo.
Let's revisit this in the future if we see that this is something we'd like to official support.
Thanks.
This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.
π Feature request
Command (mark with an
x
)Description
Switzerland has four national languages ((swiss-)german, french, italian and romansh) and english as an official language. Switzerland however has no official locale specification, so as far as I know the CLDR data is just a "best effort" for specifying the locale. For example the date format in en-CH is simply wrong (
dd/MM/y
should bedd.MM.y
). However there are also minor issues with the data; e.g. floating point numbers can be separated by both,
or.
, but.
is more common. Also date and time are not usually separated by,
, but can be.Since Angular and the Angular CLI limits the customization of locale information, this becomes a problem for the projects at SBB (national public transport provider), since the locales are specified by business for SBB projects.
Describe the solution you'd like
I would like to have a feature to provide our own locales, maybe with a warning for possible imcompatibility.
e.g.
This sould be doable, by changing
configureI18nBuild
inpackages\angular_devkit\build_angular\src\utils\i18n-options.ts
, so that it tries to resolve custom locale imports before callingfindLocaleDataPath
. I'm also fine with printing a warning to point out possible incompatiblity issues.If you are not opposed to this feature I can also provide a PR.
Describe alternatives you've considered
Either patch the locale data after startup or register all custom locales with
registerlocaledata
, which is cumbersome.