In our current project, we want to be able to live update all translated strings on the page (using
gettext) as soon as the user selects a new language.
The event is handled using
handle_event which calls
Gettext.put_locale/1 as well as assigns the locale to the socket (
assign(socket, locale: locale)).
Unfortunately, the translated strings on the page do not update for regular
<%= gettext "foo" %> tags in EEx live templates.
We currently know of two workarounds that we can apply in our application to get translated text to update immedately:
Wrap all content in the template in
Gettext.with_locale(fn -> ... end). This has the major drawback that it prevents us from using
live_componentanywhere within that function call, as Live View doesn’t manage the elements anymore.
assignswithin tags that have translated text, e.g.
<%= assigns && gettext "foo" %>or
<%= gettext "foo", locale: @locale %>. Unfortunately, this approach seems cumbersume, repetitive and (in the second variant) requires us to pass
@localedown to all views/components.
Thinking about there workarounds, I seemed to me as if gettext itself is working perfectly fine, but liveview doesn’t give it a chance to update if used in the simple form without any access to
After digging in the liveview source code, I found that tags are analyzed to find out whether they need to be re-rendered for changed assigns.
Trying to replicate the “any access to
assigns will cause a rerender” situation, I tried to create a macro like this:
defmacro trans(msgid) do quote do var!(assigns) && gettext(unquote(msgid)) end end
and use it as
<%= trans("foo") %>, but that still doesn’t update when it should.
I suspect that the macro is not expanded when the EEx template is compiled for live view and the access to
assigns is thus not recognized.
What I found to be working well, but which requires source code modification in phoenix_live_view, is adding
defp classify_taint(:gettext, _), do: :always to https://github.com/phoenixframework/phoenix_live_view/blob/900b151809ec4064f58e763c45c3906a5ff57ec2/lib/phoenix_live_view/engine.ex#L899
I’d like to hear some opinions of what would be a good solution to the problem we’re currently facing. I do understand that not all users “need” live updating translations on their page and always re-evaluating tags containing
gettext calls incurs a performance penalty when compared to evaluating them just once.
Would it make sense to allow configuring custom “signatures” in
config.exs to cater to such problems where live view can not correctly infer which tags need recomputation?