I18n segments router Phoenix

Viewed 645

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:

  1. Every use of "something_foo_path()" helpers must be replaced by this new "localized_path()"

  2. 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"

  3. I should be able to get the current locale/conn info directly in the router (feature/bugfix?) and avoid a hack like that.

1 Answers
Related