Gettext in a hex package

I am currently trying to add i18n support to the coherence package. Sadly I run into a small problem and need help.

Coherence has it’s own gettext module and because of that I have to set the current language not only in the gettext module of my app but also in coherence. Which is kinda sad, because changing the current locale in two places is problematic and leads to wrong locales when you forget that you have to do it twice. Totally sure that I miss an obvious fix for this, but I am new to elixir and this is my first time dealing with gettext.

Thanks :wink:

1 Like

I don’t believe there is much you can do. The best is to encapsulate changing all gettext backends in a single function and make sure to invoke it.

@whatyouhide do you think there is something we can do from Gettext side to streamline this?

2 Likes

Are there no other packages out there that have text inside that have translations? Maybe in coherence I am “holding it wrong”?

1 Like

Yeah we don’t support setting the locale for multiple backends. I am not sure what we can do to streamline this, but would doing something like this:

defmodule MyApp.Translations do
  def put_locale(locale) when is_binary(locale) do
    Enum.each([Coherence.Gettext, MyApp.Gettext], &Gettext.put_locale(&1, locale))
  end
end

work?

1 Like

Yes, that works. But if this is the road to go for now, I will need to explain this to users of coherence and make them use it in a correct way. Which is kinda error prone. And I also have to do something to set the default_locale in the config.exs.

1 Like

Maybe there should be some kind of get global instance call that everything hooks in to by default (perhaps even namespaced based on the application name)? That’d still leave a way for specific instances as well but everything by default would share a global (potentially namespaced translations) instance?

2 Likes

That’s a good call. We could have a Gettext.locale/0 and Gettext.locale/1 that would use gettext own’s app environment and we could make all default backends use it by default. Can someone please open up an issue?

2 Likes

Doing so now in elixir-lang/gettext, should it be put in any other repo’s as well?

EDIT: Done: Global Gettext context · Issue #147 · elixir-gettext/gettext · GitHub

5 Likes

For note, the follow-up PR by whatyouhide:

2 Likes

Btw, I just realized the approach coherence is shipping Gettext is not going to “scale”. It means users cannot change or add translations after coherence is compiled. It also means coherence would have to include translations for all used idioms, which makes it unnecessarily heavy for the majority of use cases.

My suggestion is for coherence to ship with a gettext backend with only english but provide a mechanism to configure the gettext backend. This way the user can pass their own backend with its own options. coherence could also include a generator that copies its .po files to the user application. I would suggest for those to be in the “coherence” domain (i.e. “coherence.po”).

Can someone please report/contribute this to coherence accordingly? I will be glad to help and clarify with any questions. Thank you.

4 Likes

I already wrote a generator that copies the translations to the project in my branch for this. Coherence copies templates and a few other things already. And I added the translation files into that. Those translations are in the “coherence” domain.

1 Like

We’ve added dgettext calls to the user-facing strings in coherence (using the “coherence” domain) but, as you say, there is no way to override the official translations. We have an issue discussing how best to add translations. Could you go there and give us some hints on how to handle this?

I’ve read the gettext docs at hex.pm and it hasn’t been very enlightening: The relevant section seems to be this one: https://hexdocs.pm/gettext/Gettext.html#module-configuration

In this section you say that the :otp_app for the backend must be defined at compile time and not using the mix configuration. This hardcodes the paths at which gettext wil look for the .po files, and users won’t be able to provide theirown custom .po files to override the default translations. If you know of a way that works, it would be good to document that approach somewhere (the gettext docs?), because it might be useful for other libraries.

Thanks in advance for your time

1 Like

I think we have a proper design for Gettext in Coherence now. I just pushed it to the phx-1.3 branch. I want to thank everyone who contributed, especially @tmbb and @josevalim !! I’m open to your feedback :slight_smile:

1 Like