Gettext для интернационализации
Исходный кодДля интернационализации с помощью gettext необходимо вызвать Gettext.put_locale/2 в обратном вызове монтирования LiveView, чтобы указать 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
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:
def mount(_params, %{"locale" => locale}, socket) do
Gettext.put_locale(MyApp.Gettext, locale)
{:ok, socket}
end
Это также можно инкапсулировать в хук, как описано в предыдущем разделе.
Однако, если локаль хранится в сессии, изменить её можно только с помощью обычных запросов к контроллеру. Поэтому всегда используйте <.link to={...} />, чтобы перейти к контроллеру, который соответствующим образом изменит сессию и перезагрузит LiveView.
Локаль из базы данных
Также можно разрешить пользователям хранить настройки локали в базе данных. Тогда в mount/3 можно получить идентификатор пользователя из сессии и загрузить локаль:
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 в соответствии с его предпочтительной локалью. Надеемся, это руководство подскажет, как двигаться дальше и выбрать наиболее подходящий подход для вашего приложения.
© 2014 Chris McCord
Licensed under the MIT License.
https://phoenix-live-view.hexdocs.pm/gettext.html