I have an Elixir / Phoenix app which reacts differently depending on the domain (aka tenant).
A tenant has a specific locale such as "fr_FR", "en_US" and so on.
I want to translate the URIs of the router depending the current locale:
# EN
get "/classifieds/new", ClassifiedController, :new
# FR
get "/annonces/ajout", ClassifiedController, :new
So far I thought it would be possible to do something like that (pseudo code):
if locale() == :fr do
scope "/", Awesome.App, as: :app do
pipe_through :browser # Use the default browser stack
get "/annonces/ajout", ClassifiedController, :new
end
else
scope "/", Awesome.App, as: :app do
pipe_through :browser # Use the default browser stack
get "/classifieds/new", ClassifiedController, :new
end
end
It doesn't work since the router is compiled during the boot of the server, so you have no context of the current connexion (locale, domain, host and so on).
So far my solution (which works) was to create two scopes with two aliases:
scope "/", Awesome.App, as: :fr_app do
pipe_through :browser # Use the default browser stack
get "/annonces/ajout", ClassifiedController, :new
end
scope "/", Awesome.App, as: :app do
pipe_through :browser # Use the default browser stack
get "/classifieds/new", ClassifiedController, :new
end
and a helper associated:
localized_path(conn, path, action)
which takes a path (:app_classified_new_path) and prefix with fr (:fr_app_classified_new_path) if the current locale is "fr" (for example). If the path doesn't exist for the current locale, I fallback to the default locale "en").
It's working great but I see some pain points:
Every use of "something_foo_path()" helpers must be replaced by this new "localized_path()"
The app will accept each localized segments (fr, en, it, whatever) and it's not really what I want (I want to have only the fr segments to work on the tenant "fr"
I should be able to get the current locale/conn info directly in the router (feature/bugfix?) and avoid a hack like that.