internationalization - I18n 分段路由器 Phoenix

标签 internationalization elixir phoenix-framework

我有一个 Elixir/Phoenix 应用程序,它根据域(又名租户)的不同做出不同的 react 。

租户具有特定的语言环境,例如“fr_FR”、“en_US”等。

我想根据 来翻译路由器的 URI。当前语言环境 :

# EN
get "/classifieds/new", ClassifiedController, :new

# FR
get "/annonces/ajout", ClassifiedController, :new

到目前为止,我认为有可能做这样的事情(伪代码):

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

它不起作用,因为路由器是在服务器启动期间编译的,因此您没有当前连接的上下文(区域设置、域、主机等)。

到目前为止,我的解决方案(有效)是创建两个具有两个别名的作用域:

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

和一个助手关联:

localized_path(conn, path, action)

它需要一条路径 (:app_classified_new_path) 和前缀 fr ( :fr_app_classified_new_path ) 如果当前语言环境是“ fr ”(例如)。如果当前语言环境不存在路径,我将回退到默认语言环境 "zh" )。

它工作得很好,但我看到了一些痛点:
  • 每次使用“something_foo_path()”助手都必须被这个新的“localized_pa​​th()”替换
  • 该应用程序将接受每个本地化段(fr、en、it 等等),这并不是我真正想要的(我只想让 fr 段处理租户“fr”
  • 我应该能够直接在路由器中获取当前的语言环境/连接信息(功能/错误修复?)并避免这样的黑客攻击。
  • 最佳答案

    看看这篇文章Practical i18n with Phoenix and 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
    

    关于internationalization - I18n 分段路由器 Phoenix,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44019900/

    相关文章:

    java - Spring 国际化 : How to dynamically set locale value

    elixir - 如何在 Ecto 模型中使用 uuid

    elixir - 如何创建 XML Http 请求?

    elixir - UndefinedFunctionError - phoenix/ecto 中的 iex 别名

    java - 有什么方法可以检测 Java 中的 RTL 语言吗?

    javascript - 将语言作为动态属性从父组件传递给 React 中的所有后代

    ruby-on-rails - Rails 如何本地化表单对象的属性

    erlang - Dialyzer 说函数永远不会被调用,即使它是

    elixir - 关于在模块内调用宏

    api - 为不同的管道呈现不同的错误(:api and :browser)?