Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regional and scripts specific locals #202

Open
sabify opened this issue Mar 1, 2025 · 15 comments
Open

Regional and scripts specific locals #202

sabify opened this issue Mar 1, 2025 · 15 comments

Comments

@sabify
Copy link
Contributor

sabify commented Mar 1, 2025

Is there any way to define and use regional and script specific locals?

For example:

├── locales
│   ├── en-US.json
│   ├── en-GB.json
│   └── en-latn-US-Valencia.json

Comprehensive langid/locale handling: https://unicode-org.github.io/icu4x/rustdoc/icu/locale/struct.LanguageIdentifier.html / https://docs.rs/icu/latest/icu/locid/struct.Locale.html

@Baptistemontan
Copy link
Owner

Baptistemontan commented Mar 1, 2025

Technically, there should be no problem for en-US or en-GB, I'm pretty sure it should work out of the box, but en-latn-US-Valencia would be morre tricky due to

quote!(const #ident: &l_i18n_crate::reexports::icu::locid::Locale = &l_i18n_crate::reexports::icu::locid::locale!(#locale);)

as stated by the locale! doc:

Note: The macro cannot produce locales with more than one variant or multiple extensions (only single keyword unicode extension is supported) due to const limitations (see Heap Allocations in Constants):

@Baptistemontan
Copy link
Owner

We could instead of having a constant, use a lazy initialized static and parse the locale on first access, if you want to make that change I'm open for a PR

@Baptistemontan
Copy link
Owner

The real question would probably be about translations duplication, if for example en-US could just override some keys of en

@Baptistemontan
Copy link
Owner

Wait I missread the docs, en-latn-US-Valencia has a single variant and no extension, I just tried and it works fine

@Baptistemontan
Copy link
Owner

The Locale enum variant for en-latn-US-Valencia will be Locale::en_latn_US_Valencia

@sabify
Copy link
Contributor Author

sabify commented Mar 1, 2025

Amazing! Thanks for your prompt attention.

So we may want to wait for niche use cases of locale to change the behavior of the initialization?

@Baptistemontan
Copy link
Owner

yep we can wait, until someone with "sl-IT-rozaj-biske-1994" or other obscure locales open an issue, I consider it working

@Baptistemontan
Copy link
Owner

Baptistemontan commented Mar 1, 2025

But I'll look into extending / overriding / de-duplicate other locales translations

@Baptistemontan
Copy link
Owner

The logic is feasible, the question is how complicated it gets, technically it was done for defaulted values before the rewrite for the dynamic loading, but now that static strings are regrouped it gets more complicated so I skipped it, might want to re-introduced it

@Baptistemontan
Copy link
Owner

Baptistemontan commented Mar 2, 2025

Most of the work has been done in #206 , now it's just a matter of how to define defaults, something like

[package.metadata.leptos-i18n]
default = "en"
locales = ["en", "fr", "en-GB", "fr-CA"]
extends = { fr-CA = "fr" }

Not sure about the name tho

@sabify
Copy link
Contributor Author

sabify commented Mar 3, 2025

@Baptistemontan Shouldn't that be done automatically? We can detect the language with LanguageIdentifier's language field and default any region related to that language if the base language exists.

- en-GB, en-US will be defaulted to en if exists, or the global default locale, and the en will be defaulted to the global locale.

- fr-CA will be defaulted to fr if exists, or the global default locale, and the fr will be defaulted to the global locale.

This logic is clear and will not also introduce circular dependencies.

IMHO, with the logic introduced in #206 it makes it much harder to maintain the translations and the default logic behind it...

@Baptistemontan
Copy link
Owner

#206 did not introduce any new logic for the user, nothing changed other than how default values are handled and their observable behavior is exactly the same as before

@Baptistemontan
Copy link
Owner

Baptistemontan commented Mar 3, 2025

my comment above is just a proposition, and yes your comment make sense, but I prefer to minimize implicit behavior and allow customization when it's really easy to introduce. If the user wants en_US to extend en_GB that itself extend en then I'll let him do that
And tbh circular defaults aren't a problem, as they will be a chain, and the default locale will be the last one, so even if you have

extends = { fr-CA = "fr", fr = "fr-CA" }

if a key is missing in both, default to en. It's just not very not interesting to do it from the user perspective, mostly every user will have well defined and not ambiguous depedencies.

Can you elaborate on how this would make translations harder to maintain ?

@sabify
Copy link
Contributor Author

sabify commented Mar 3, 2025

Sorry for my bad understanding of your PR comments.

I'm not against having a feature to control the inheritance of locales. I've proposed a global common-sense logic on the inheritance which it doesn't require configuring it by hand.

In other cases that a user needs to change the order of inheritance, they can do it by your proposed extends keyword.

About naming your feature, I think inherits keyword be meaningful here?

inherits = { fr-CA = "fr" } means fr-CA inherits from fr.

@Baptistemontan
Copy link
Owner

Tbh both can be implemented, and both make sense, but introducing your proposition will need a major version bump as it will implicitly change some behavior. I'm not against it, but for now I'll go with the inheritance, and adding an implicit default to the base locale will be almost trivial in the future

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants