ChristophP / elm-i18next

https://package.elm-lang.org/packages/ChristophP/elm-i18next/latest
BSD 3-Clause "New" or "Revised" License
67 stars 13 forks source link

Routing based translations #3

Closed mccrodp closed 7 years ago

mccrodp commented 7 years ago

Have you implemented translations based on routes before?

I asked this question over on Elm Slack Channel. Looking to have groups of translations tied to a particular key, i.e. - en or jp and set the active key based on route.

E.g. : /jp/about/ loads all Japanese translations via jp key for the about route and so on with en for English translations, etc.

Would you have any suggestions on something like this?

mccrodp commented 7 years ago

I have perhaps found my answer, load a different translation file based on route:

init =
    ( Model initialTranslations, fetchTranslations TranslationsLoaded "/locale/translations.en.json" )

Just to find out how to do this now, will report back when I solve 😄

mccrodp commented 7 years ago

This is as far as I got. The translation JSON does not seem to load properly even without the update fn as it is. In your Testpage I saw it had similar loading syntax including the URI,, starting from /locale/, but not luck yet. https://github.com/mccrodp/brunch-with-elm-bootstrap/tree/add-translations

Will keep at it.

mccrodp commented 7 years ago

Got it working at that repo, it loads English initially and then in the update fn straight away loads the Japanese and displays.

Just need to trigger my language updates based on routes now and then I am a happy man.

Thank you so much for this repo, awesome job! 😄

ChristophP commented 7 years ago

Cool, looks like you are getting it to work. It really should just be a matter of triggering a fetch on a route change I think. I am really glad you like it the package and find it helpful. This thing was born a little bit out of desperation. My company is really locked in on i18next that it would have been a show stopper for using elm. So i kinda thought if I don't find a solution for this we won't be able to use it. So I am really happy that this helps you out too. Thanks you for the feedback. :-)

ChristophP commented 7 years ago

PS: Do you still need this issue, or can we close it?

mccrodp commented 7 years ago

All good, we can close, might post back working solution afterwards in case it helps others. Cheers.

mccrodp commented 7 years ago

I'm still a bit confused how this works, its more my Elm knowledge in general I imagine.

I've integrated the local JSON and the package now into a branch on my real project that has the routing in place.

How do I just set translations to load from a different locale / JSON file? At the moment I have this in my HandleRoute I just load the new model and call FetchTranslations: https://github.com/ahimsayoga/brunch-with-elm-bootstrap/blob/translations/app/elm/Main.elm#L130

I would like to be able to do something like this (load different JSON on contact route), but I just don't know how to use the fetchTranslation code in the way intended:

ContactR ->
    { newModel | translations = fetchTranslations TranslationsLoaded "/locale/translations.en.json" }

I have seen some of the code in the Test.elm, but it all seems to be based on JSON loaded into memory, I only want to load into memory if a particular route is selected, not have all translations loaded into memory from the start. Does that make sense?

Thanks again for any tips.

ChristophP commented 7 years ago

So if i am understanding correctly from your code you want to load the app with some translation and then load a different JSON file whenever the language changes and also only keep the current language in memory. Maybe you could do it like this:

module Main exposing (..)

handleRoute : Sitemap -> Model -> ( Model, Cmd Msg )
handleRoute route ({ ready } as model) =
    let
        newModel =
            { model | route = route }

        -- just pseudo code here, use some String or Regex
        -- to parse langauge out of the route
        lang =
            Regex.match route

        -- store the current lang in your model and check against it to know when the
        -- language changed(you will also have to update model.currentLang somewhere)
        fetchLang =
            if lang != model.currentLang then
                fetchTranslations TranslationsLoaded "/locale/translations." ++ lang ++ ".json"
            else
                Cmd.none
    in
        case route of
            HomeR ->
                newModel ! [ fetchLang ]

            ContactR ->
                newModel ! [ fetchLang ]

            _ ->
                newModel ! []

You think that would work?

ChristophP commented 7 years ago

So basically in a nutshell: In your model you store the current language(i.e. "jp"). Then on every url change you check if the current language changed(i.e. "en"). If it does, you load the translations for the new language and set model.currentLanguage and model.translations.

mccrodp commented 7 years ago

Quick update to say I got this working fundamentally with a minimal version of your suggestion. Just need to apply it to the specific context of the app for switching languages now. Will post what I get here as an example when done.

A big thank you again for the repo and Elm help in general, have a better understanding in general now 😄

ChristophP commented 7 years ago

Sweet, glad it's working out or ya. Let me know how it goes.