reflex-dev / reflex

🕸️ Web apps in pure Python 🐍
https://reflex.dev
Apache License 2.0
19.05k stars 1.08k forks source link

Internationalization (I18N) and localization (L10N) (Feature Request) #2339

Open karndeb opened 8 months ago

karndeb commented 8 months ago

Feature Request Hi team, Great work and library. I think with internationalization the use cases and reflex adoption will greatly improve. I have two ways in my mind that we can add this. One is quick and easy which is through the middleware route and using the gettext module or adding i18n to the core jinja extensions. Will probably need help on the latter. Let me know if this is in the roadmap. Thanks

masenf commented 8 months ago

Internationalization is important to the team and on the roadmap, but it's not currently a focus for any particular developer. We don't have a particular strategy around this area, but something which can enable translation support and also enable the CMS workflow would be ideal.

I'm imagining something like State, except all users accessing the site share the same values for a given key and the set of values can be swapped out by some identifier (language, for example).

woernerm commented 5 months ago

There is a great translation framework currently in development by the Mozilla Foundation, called project fluent. I think it is beautiful, because

Existing implementations of the fluent language can be found here.

I think it would be great to have it implemented as a component so that you can write:

def headline():
    return rx.text(
        rx.translation("my_special_headline"), 
        color="blue"
    )

where "my_special_headline" is the ID of the translation string to use. In addition, variables may be passed to the translation system as shown below. Sticking with the example given on the fluent page (showing a warning before closing all open tabs in a browser), one could write:

def warning():
    return rx.text(
        rx.translation("tabs-close-warning", MyState.number_of_open_tabs), 
        color="red"
    )

For a language like Polish which has more than one plural form, fluent would then select the appropriate translation depending on the number of open tabs:

paoloemilioserra commented 3 months ago

I tried something with @masenf suggestion if I interpreted it correctly https://github.com/paoloemilioserra/reflex-i18n/tree/master any feedback is much appreciated

benedikt-bartscher commented 3 months ago

@paoloemilioserra thanks for sharing! It seems like you forgot to make the repository public?

paoloemilioserra commented 3 months ago

@benedikt-bartscher you should be able to see it now

abulvenz commented 2 months ago

@masenf

I'm imagining something like State, except all users accessing the site share the same values for a given key and the set of values can be swapped out by some identifier (language, for example).

This reminds me of the tiny feature request https://github.com/reflex-dev/reflex/issues/2771 Maybe it could go like this:

class AppState(rx.State):  
  @rx.var
  def user_language(self) -> str:
     ...
   ...

@rx.scope(var=AppState.user_language)
class T(AppState):
  ...
  # vars are added at compile time using po files.

# Somewhere else
@rx.page
def index():
  return rx.text(f"{T.hello_user} {AppState.user_name}")

The benefit would be: One state per used language on the server only.

Maybe it is wrong to stack one dream API :rainbow: on top of the other :cloud:

But when thinking about it the requirements might become more clear: