查看源代码 Gettext 用于国际化

对于使用 gettext 进行国际化,您需要在 LiveView 的 mount 回调中调用 Gettext.put_locale/2 来指示 LiveView 应该使用哪个语言环境来渲染页面。

然而,一个需要回答的问题是如何在第一时间获取语言环境。有很多方法可以解决这个问题。

  1. 语言环境可以存储在 URL 中作为参数。
  2. 语言环境可以存储在会话中。
  3. 语言环境可以存储在数据库中。

我们将简要介绍这些方法,以提供一些方向。

来自参数的语言环境

您可以说所有 URL 都包含一个语言环境参数。在您的路由器中

scope "/:locale" do
  live ...
  get ...
end

访问没有语言环境的页面应该自动重定向到包含语言环境的 URL(最佳语言环境可以从 HTTP 头获取,这超出了本指南的范围)。

然后,假设所有 URL 都包含语言环境,您可以相应地设置 Gettext 语言环境。

def mount(%{"locale" => locale}, _session, socket) do
  Gettext.put_locale(MyApp.Gettext, locale)
  {:ok, socket}
end

您也可以使用 on_mount 钩子来自动为应用程序中的每个 LiveView 恢复语言环境。

defmodule MyAppWeb.RestoreLocale do
  def on_mount(:default, %{"locale" => locale}, _session, socket) do
    Gettext.put_locale(MyApp.Gettext, locale)
    {:cont, socket}
  end

  # catch-all case
  def on_mount(:default, _params, _session, socket), do: {:cont, socket}
end

然后,将此钩子添加到 def live_view 下的 MyAppWeb 中,以便默认情况下对所有 LiveView 运行它。

def live_view do
  quote do
    use Phoenix.LiveView,
      layout: {MyAppWeb.Layouts, :app}

    on_mount MyAppWeb.RestoreLocale
    unquote(view_helpers())
  end
end

请注意,由于 Gettext 语言环境没有存储在 assigns 中,如果您想更改语言环境,必须使用 <.link navigate={...} />,而不能简单地修补页面。

来自会话的语言环境

您也可以将语言环境存储在 Plug 会话中。例如,在控制器中,您可能需要执行以下操作。

def put_user_session(conn, current_user) do
  Gettext.put_locale(MyApp.Gettext, current_user.locale)

  conn
  |> put_session(:user_id, current_user.id)
  |> put_session(:locale, current_user.locale)
end

然后,在 LiveView mount 中从会话中恢复语言环境。

def mount(_params, %{"locale" => locale}, socket) do
  Gettext.put_locale(MyApp.Gettext, locale)
  {:ok, socket}
end

您也可以像上一节一样将其封装在钩子中。

但是,如果语言环境存储在会话中,您只能通过使用常规控制器请求来更改它。因此,您应该始终使用 <.link to={...} /> 指向相应的更改会话的控制器,并重新加载任何 LiveView。

来自数据库的语言环境

您也可以允许用户将他们的语言环境配置存储在数据库中。然后,在 mount/3 上,您可以从会话中检索用户 ID 并加载语言环境。

def mount(_params, %{"user_id" => user_id}, socket) do
  user = Users.get_user!(user_id)
  Gettext.put_locale(MyApp.Gettext, user.locale)
  {:ok, socket}
end

实际上,您最终可能会混合使用这里列出的多种方法。例如,从数据库读取非常适合用户登录后,但在登录之前,您可能需要将语言环境存储在会话或 URL 中。

同样,您可以将语言环境保留在 URL 中,但根据用户偏好的语言环境相应地更改 URL,一旦他们登录。希望本指南能为您提供一些建议,让您能够继续前进,并探索最适合您应用程序的方法。