purescript-flame icon indicating copy to clipboard operation
purescript-flame copied to clipboard

Internationalisation

Open asvanberg opened this issue 2 years ago • 5 comments

Right now the user-facing elements/attributes text, alt, placeholder, and any others are hard-coded to String.

If you want to localise an application you need access to the current language everywhere to make the proper translation. It would be better if Html had a second type hole so you can define your views something like Html message text. Then a Flame provided function localise :: (text -> a) -> Html message text -> Html message a can be used to translate everything into Html message String which can be returned from the view function of the application. If you do not need internationalisation you can just keep using String and no changes are required.

asvanberg avatar Jan 28 '22 22:01 asvanberg

Hi again @asvanberg . I am trying to understand your proposal. What advantages does a built in localize function would have over a third party library or some other ad hoc method?

easafe avatar Jan 28 '22 22:01 easafe

I do not understand what you mean be "ad hoc method" and I can't see how a third party library can interact with the foreign type Html message to do any type of localisation.

I'll create a more complete example if that helps

type Model = { language :: Language }

view :: Model -> Html message
view model = [a long call chain to render the entire view which eventually calls viewLoginForm]

viewLoginForm :: Html message
viewLoginForm = form
  [ label "E-mail", input [ placeholder "E-mail" ]
  , label "Password", input [ placeholder "Password" ]
  , button "Register
  ]

How would I go about translating those strings? Right now I'm forced to pass model.language all the way down so that I can do

data LocalisedString = Email | Password | Register

translate :: Language -> LocalisedString -> String

viewLoginForm language = form
  [ label (translate language Email), input [ placeholder (translate language Email) ]
  , ...
  ]

It would be more convenient if I in my top level view function could do

view :: Model -> Html message
view model = localise (translate model.language) $ buildTheEntireView model

buildTheEntireView :: Model -> LocalisableHtml message LocalisedString
buildTheEntireView = [long call chain that ends with viewLoginForm]

viewLoginForm :: LocalisableHtml message LocalisedString
viewLoginForm language = form
  [ label Email, input [ placeholder Email ]
  , ...
  ]

asvanberg avatar Jan 28 '22 23:01 asvanberg

Ad hoc like label' :: DataType -> Html a.

That being said, built in internationalization makes sense and it would be more convenient (but I think we could get away with just making the type of label/placeholder/text/etc more general instead of adding an extra parameter to Html, no?)

In any case, if you'd like to take a shot at this, PRs are welcome :)

easafe avatar Jan 29 '22 00:01 easafe

I'm new to PureScript so not sure I can manage this when it would appear to involve FFI/JavaScript. This is why I wanted #54 to make it easier to accomplish things like this in just PureScript.

As for just making the label/.../etc more general instead of an extra parameter to Html is just implementation details. What I want to be able to do is to have the ability to use a custom datatype that can be translated later, how it is done is not very important.

If label accepted any a how would that information be conveyed from Html message and how to apply the translation function?

asvanberg avatar Jan 29 '22 10:01 asvanberg

I'm new to PureScript so not sure I can manage this when it would appear to involve FFI/JavaScript. This is why I wanted #54 to make it easier to accomplish things like this in just PureScript.

This would probably take a small amount of JavaScript, but I don't think you'd have to touch the hairy bits, like the renderer.

If label accepted any a how would that information be conveyed from Html message and how to apply the translation function?

The easy way that avoids breaking changes would be a new type class.

easafe avatar Jan 29 '22 15:01 easafe

After actually trying an implementation, I am closing this. The added complexity to the library code does not justify the gains of not having to thread a parameter.

easafe avatar Aug 26 '22 21:08 easafe