GETTEXT: Invisible locale files!

Hi there,

I use gettext with Phoenix. I’ve created a tiny project with a a home page, a plug to set the locale
and three languages: en, fr, it. Here’s the structure I get.

priv/gettext
└─ en
| └─ LC_MESSAGES
| └─ errors.po
| └─ default.po
└─ fr
| └─ LC_MESSAGES
| └─ errors.poI
| └─ default.po
└─ it
| └─ LC_MESSAGES
| └─ errors.po
| └─ default.po
└─ default.pot
└─ errors.pot

The plug is the one in the official Plug documentation and is working. It sets the right locale which I can see in conn.assigns.

When I change the values in ‘en/LC_MESSAGES/default.po’ it works and I see the change, but the app ignores whatever
I put in the ‘fr’ and ‘it’ files. When I run the command: “mix gettext.extract --merge” nothing happens.
My changes are still there. Nothing iis overwritten by all those files are invisible to gettext.

Any idea?

Thanks in advance

I think when you create a new locale you need to recompile Gettext with mix deps.compile gettext --force then run mix gettext,extract --merge.

Thanks Kip for the reply.
Eventually I found the reason why Gettext didn’t see my set locale. Here’s how my code in the SetLocale plug was

defmodule MyProjectWeb.Plugs.SetLocale do
import Plug.Conn

@locales [“en”, “fr”, “fa”, “it”]

def init(opts), do: opts

def call(%Plug.Conn{params: %{“locale” => loc}} = conn, _opts) when loc in @locales do
assign(conn, :locale, loc)
end
def call(conn, default), do assign(conn, :locale, default)

end

This is exactly what the official documentation on Plug suggests. What the documentation does not say is that this is not enough if we’re using Getthext. Gettext has its own store to hold state. The scope of this state does not go beyond the request and this is exactly what we need in this case. I just added the missing code for the Gettext and it’s now up and running. New code goes like this.

defmodule MyProjectWeb.Plugs.SetLocale do
import Plug.Conn

@locales [“en”, “fr”, “fa”, “it”]

def call(%Plug.Conn{params: %{“locale” => loc}} = conn, _opts) when loc in @locales do
Gettext.put_locale(AuthExWeb.Gettext, loc)
assign(conn, :locale, loc)
end

def call(conn, default) do
Gettext.put_locale(AuthExWeb.Gettext, default)
assign(conn, :locale, default)
end
end

I tried to fork/update the relevant documentation page and add this point but it was not on Github. If some of the Phoenix contributors read this I suggest to add it to the documentation. I guess amongst those who are interested in locale setting, many use Gettext.

I might suggest one small change. Instead of

@locales ["en", "fr", "fa", "it"]

I would suggest

@locales Gettext.known_locales(YourGettextModule)

which means your code will adapt to your locale configuration rather than having to maintain it in more than one place.

Perfect point. I changed my code. I was not happy with that line. I used the same pattern in my Rails project to avoid the hard coded constants.
Thanks

Exact.