查看源代码 Gettext 用于国际化
对于使用 gettext 进行国际化,您需要在 LiveView 的 mount 回调中调用 Gettext.put_locale/2
来指示 LiveView 应该使用哪个语言环境来渲染页面。
然而,一个需要回答的问题是如何在第一时间获取语言环境。有很多方法可以解决这个问题。
- 语言环境可以存储在 URL 中作为参数。
- 语言环境可以存储在会话中。
- 语言环境可以存储在数据库中。
我们将简要介绍这些方法,以提供一些方向。
来自参数的语言环境
您可以说所有 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,一旦他们登录。希望本指南能为您提供一些建议,让您能够继续前进,并探索最适合您应用程序的方法。