Support multiple locales formally

elixir gettext current does not fully support fallback to another language [0].
But it might in the future. We adapt it so that all languages in Accept-Language
headers are received by Pleroma.Web.Gettext. User.languages is now a comma-separated
list.

[0]: https://github.com/elixir-gettext/gettext/issues/303
This commit is contained in:
Tusooa Zhu 2022-03-03 02:03:44 -05:00
commit 7ea330b4fe
No known key found for this signature in database
GPG key ID: 7B467EDE43A08224
3 changed files with 89 additions and 17 deletions

View file

@ -65,6 +65,24 @@ defmodule Pleroma.Web.Gettext do
end
end
def get_locales() do
Process.get({Pleroma.Web.Gettext, :locales}, [])
end
def is_locale_list(locales) do
Enum.all?(locales, &is_binary/1)
end
def put_locales(locales) do
if is_locale_list(locales) do
Process.put({Pleroma.Web.Gettext, :locales}, Enum.uniq(locales))
Gettext.put_locale(Enum.at(locales, 0, Gettext.get_locale()))
:ok
else
{:error, :not_locale_list}
end
end
def locale_or_default(locale) do
if supports_locale?(locale) do
locale
@ -73,11 +91,46 @@ defmodule Pleroma.Web.Gettext do
end
end
defmacro with_locale_or_default(locale, do: fun) do
def with_locales_func(locales, fun) do
prev_locales = Process.get({Pleroma.Web.Gettext, :locales})
put_locales(locales)
try do
fun.()
after
if prev_locales do
put_locales(prev_locales)
else
Process.delete({Pleroma.Web.Gettext, :locales})
end
end
end
defmacro with_locales(locales, do: fun) do
quote do
Gettext.with_locale(Pleroma.Web.Gettext.locale_or_default(unquote(locale)), fn ->
Pleroma.Web.Gettext.with_locales_func(unquote(locales), fn ->
unquote(fun)
end)
end
end
def to_locale_list(locale) when is_binary(locale) do
locale
|> String.split(",")
|> Enum.filter(&supports_locale?/1)
end
def to_locale_list(_), do: []
defmacro with_locale_or_default(locale, do: fun) do
quote do
Pleroma.Web.Gettext.with_locales_func(
Pleroma.Web.Gettext.to_locale_list(unquote(locale))
|> Enum.concat(Pleroma.Web.Gettext.get_locales()),
fn ->
unquote(fun)
end
)
end
end
end

View file

@ -11,22 +11,27 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do
def init(_), do: nil
def call(conn, _) do
locale = get_locale_from_header(conn) || Gettext.get_locale()
Gettext.put_locale(locale)
assign(conn, :locale, locale)
locales = get_locales_from_header(conn)
first_locale = Enum.at(locales, 0, Gettext.get_locale())
Pleroma.Web.Gettext.put_locales(locales)
conn
|> assign(:locale, first_locale)
|> assign(:locales, locales)
end
defp get_locale_from_header(conn) do
defp get_locales_from_header(conn) do
conn
|> extract_preferred_language()
|> normalize_language_codes()
|> first_supported()
|> all_supported()
end
defp first_supported(locales) do
defp all_supported(locales) do
locales
|> Enum.flat_map(&Pleroma.Web.Gettext.supported_variants_of_locale/1)
|> Enum.find(&supported_locale?/1)
|> Enum.filter(&supported_locale?/1)
end
defp normalize_language_codes(codes) do