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:
parent
d3f3f30c6a
commit
7ea330b4fe
3 changed files with 89 additions and 17 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue