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 text
s 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.