I18n Phoenix Router Segment

I have an Elixir / Phoenix application that reacts differently depending on the domain (aka tenant).

The tenant has a specific language, such as "fr_FR", "en_US", etc.

I want to translate the router URI depending on 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 this (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

This does not work, since the router was compiled during server boot, so you do not have the context of the current connection (locale, domain, host, etc.).

So far, my solution (which works) has been to create two areas 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 associate assistant:

localized_path(conn, path, action)

(: app_classified_new_path) fr (: fr_app_classified_new_path), " fr" (). , "ru" ).

, :

  • "something_foo_path()" "localized_path()"

  • (fr, en, it, whatever), , ( , fr "fr"

  • locale/conn (/bugfix?) .

+4
1

i18n Phoenix Elixir. , , .

, . , . .

defmodule LocalRoutes.Web.Router do
  use LocalRoutes.Web, :router

  @locales ~w(en fr)
  import LocalRoutes.Web.Gettext
  use LocalRoutes.LocalizedRouter

  def locale(conn, locale) do
    Plug.Conn.assign conn, :locale, locale
  end

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/", LocalRoutes.Web do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index
  end
  for locale <- @locales do
    Gettext.put_locale(LocalRoutes.Web.Gettext, locale)

    pipeline String.to_atom(locale) do
      plug :accepts, ["html"]
      plug :fetch_session
      plug :fetch_flash
      plug :protect_from_forgery
      plug :put_secure_browser_headers
      plug :locale, locale
    end

    scope "/", LocalRoutes.Web do
      pipe_through String.to_atom(locale) 
      get "/#{~g"classifieds"}", ClassifiedController, :index
      get "/#{~g"classifieds"}/#{~g"new"}", ClassifiedController, :new
      get "/#{~g"classifieds"}/:id", ClassifiedController, :show
      get "/#{~g"classifieds"}/:id/#{~g"edit"}", ClassifiedController, :edit
      post "/#{~g"classifieds"}", ClassifiedController, :create
      patch "/#{~g"classifieds"}/:id", ClassifiedController, :update
      put "/#{~g"classifieds"}/:id", ClassifiedController, :update
      delete "/#{~g"classifieds"}/:id", ClassifiedController, :delete
    end
  end
end

defmodule LocalRoutes.LocalizedRouter do

  defmacro __using__(opts) do
    quote do
      import unquote(__MODULE__)
    end
  end

  defmacro sigil_g(string, _) do
    quote do
      dgettext "routes", unquote(string) 
    end
  end
end
+1

Source: https://habr.com/ru/post/1677331/


All Articles