ficusjs / ficusjs-i18n

Functions for managing translations and localization in FicusJS components
MIT License
1 stars 1 forks source link

Allowing customization of URL-based locale detection rule #53

Closed mesr closed 1 year ago

mesr commented 1 year ago

I would like to propose and, if approved, offer to implement the possibility for client code to customize — and even de-activate — the URL-based language detection rule that is currently hard-coded around the lang query-string parameter. Use cases for such a feature abound in the wild:

Updates to the source code would preserve compatibility with the current I18n module's API by keeping the current hard-coded rule as a default value, while providing an additional setter function (namely setLocaleDetectionRule(rule)) for changing or de-activating the locale detection rule dynamically.

The rule function, by its nature, would actually not be limited to URL-based detection. It is easy to imagine that such a function could pull its return value from e.g. an attribute defined on the component, an app-wide store or an async HTTP request to a back-end server. Therefore, rule functions returning a promise that resolve to a locale string would also be supported.

Types, tests and documentation would be updated accordingly.

What would be the maintainer's position on such a feature? Any additional suggestions?

ducksoupdev commented 1 year ago

@mesr I really like your idea, it will allow locale detection to be flexible and keep the API lightweight. Go ahead and submit a PR and we'll be happy to review it.

mesr commented 1 year ago

Great! Thank you @ducksoupdev.

In the current source code, the detected locale is guarantied to be a string, since it is obtained through properties or functions that are themselves guarantied to hold or return string values. Allowing client code to determine that value means that we now need to deal with arbitrary types. I am trying to account for all possible cases in a simple, meaningful and intuitive manner without doing error-checking and hard-coding throw statements.

As a general approach, when the rule parameter passed by client code to the new setLocaleDetectionRule(rule) function is itself a function, it is internally saved as is. In all other cases, it is taken as a constant value and is internally converted to a function that invariably returns that value.

The question is then: how do we handle the various types that can be returned by that function? I see two possibilities:

  1. string vs non-string: If the return type is a string, or a promise that resolves to a string, it is interpreted as a locale string and the active locale is set to that value. All other types are considered invalid, prompting the locale detection mechanism to proceed with the fallback detection methods. This would have the consequence of allowing the empty string as a valid locale name;

  2. truthy vs falsy: If the return type is a truthy value, or a promise that resolves to a truthy value, it is assumed to be a locale name and, if not already a string, type-casted to a string before setting the active locale to that value. Receiving a falsy value, or a promise that resolves to a falsy value, would prompt the locale detection mechanism to proceed with the fallback detection methods. This would have the consequence of allowing objects that convert to e.g. '[object Object]' as valid locale names, while disallowing the empty string and the number 0.

Your feedback on which approach would be more in line with FicusJS' design philosophy would be appreciated. Thank you in advance.

mesr commented 1 year ago

I have submitted the PR for the update to the i18n package and am currently working on updating the documentation accordingly.

A few noteworthy points:

ducksoupdev commented 1 year ago

Implemented with #54