I’ve been thinking about the topic of translations, especially in the context of elm-ui.
What I’ve come up with is a proof of concept API that is an almost drop in replacement for elm-ui (except for text nodes).
The main difference is that Element msg is replaced with context -> Element msg, so that when you’re building strings that need to be localized you can retrieve data from the context object. The context is passed around implicitly with row, column, and other containers, and is accessible to attributes and text nodes.
Example API:
type alias ElementC context msg = context -> ( Element msg, Element context )
type alias AttributeC context msg = context -> Attribute msg
row : List (AttributeC context msg) -> List (ElementC context msg) -> ElementC context msg
padding : Int -> AttributeC context msg
invariantText : String -> ElementC context msg -- Untranslated text
layout : context -> List (AttributeC context msg) -> ElementC context msg -> Html msg
Example view:
innerView : Model -> Element Msg
innerView model =
Element.column [ Element.spacing 10, Element.padding 10 ]
[ Element.invariantText <| String.fromInt model.count
, Element.row [ Element.spacing 10 ]
[ Input.button []
{ onPress = Just Inc
, label = Element.text .inc (\l10n inc -> { l10n | inc = inc })
}
, Input.button []
{ onPress = Just Dec
, label = Element.text .dec (\l10n dec -> { l10n | dec = dec })
}
]
, case model.lang of
En ->
Input.button []
{ onPress = Just <| Lang It
, label = Element.invariantText "🇮🇹 Italiano"
}
It ->
Input.button []
{ onPress = Just <| Lang En
, label = Element.invariantText "🇺🇸/🇬🇧 English"
}
]
This looks reasonable, except for one detail: why does text ask for setters too?
That’s the other interesting feature: you can reuse the same view code, by “linking” it with a special version of the library to have a “translatable” version of your application, where texts are replaced by Input.text and instead of an Html msg you receive an Html context.
translationLayout : context -> List (AttributeC context msg) -> ElementC context msg -> Html context
This means that you can have a toggle between a “working” view and a “translating” view.
For more details check out the repository, you can run elm reactor either in the root for the “production” website, or in the translator directory for the “translatable” website.