Support multiple locales from userLanguage cookie

This commit is contained in:
Tusooa Zhu 2022-03-03 02:31:36 -05:00
parent 7ea330b4fe
commit aca11fb70e
No known key found for this signature in database
GPG key ID: 7B467EDE43A08224
3 changed files with 39 additions and 17 deletions

View file

@ -37,7 +37,7 @@ defmodule Pleroma.Web.Gettext do
def normalize_locale(locale) do def normalize_locale(locale) do
if is_binary(locale) do if is_binary(locale) do
String.replace(locale, "-", "_") String.replace(locale, "-", "_", global: true)
else else
nil nil
end end
@ -51,13 +51,28 @@ defmodule Pleroma.Web.Gettext do
def variant?(locale), do: String.contains?(locale, "_") def variant?(locale), do: String.contains?(locale, "_")
def supported_variants_of_locale(locale) do def language_for_variant(locale) do
cond do Enum.at(String.split(locale, "_"), 0)
variant?(locale) -> end
[locale]
def ensure_fallbacks(locales) do
locales
|> Enum.flat_map(fn locale ->
others = other_supported_variants_of_locale(locale)
|> Enum.filter(fn l -> not Enum.member?(locales, l) end)
[locale] ++ others
end)
end
def other_supported_variants_of_locale(locale) do
cond do
supports_locale?(locale) -> supports_locale?(locale) ->
[locale] []
variant?(locale) ->
lang = language_for_variant(locale)
if supports_locale?(lang), do: [lang], else: []
true -> true ->
Gettext.known_locales(Pleroma.Web.Gettext) Gettext.known_locales(Pleroma.Web.Gettext)

View file

@ -26,11 +26,12 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do
|> extract_preferred_language() |> extract_preferred_language()
|> normalize_language_codes() |> normalize_language_codes()
|> all_supported() |> all_supported()
|> Enum.uniq()
end end
defp all_supported(locales) do defp all_supported(locales) do
locales locales
|> Enum.flat_map(&Pleroma.Web.Gettext.supported_variants_of_locale/1) |> Pleroma.Web.Gettext.ensure_fallbacks()
|> Enum.filter(&supported_locale?/1) |> Enum.filter(&supported_locale?/1)
end end
@ -53,8 +54,7 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do
[] []
fe_lang -> fe_lang ->
[fe_lang] String.split(fe_lang, ",")
|> ensure_language_fallbacks()
end end
end end
@ -67,7 +67,6 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do
|> Enum.sort(&(&1.quality > &2.quality)) |> Enum.sort(&(&1.quality > &2.quality))
|> Enum.map(& &1.tag) |> Enum.map(& &1.tag)
|> Enum.reject(&is_nil/1) |> Enum.reject(&is_nil/1)
|> ensure_language_fallbacks()
_ -> _ ->
[] []
@ -89,11 +88,4 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do
%{tag: captures["tag"], quality: quality} %{tag: captures["tag"], quality: quality}
end end
defp ensure_language_fallbacks(tags) do
Enum.flat_map(tags, fn tag ->
[language | _] = String.split(tag, "-")
if Enum.member?(tags, language), do: [tag], else: [tag, language]
end)
end
end end

View file

@ -75,6 +75,21 @@ defmodule Pleroma.Web.Plugs.SetLocalePlugTest do
assert %{locale: "ru", locales: ["ru", "fr", "en"]} = conn.assigns assert %{locale: "ru", locales: ["ru", "fr", "en"]} = conn.assigns
end end
test "it assigns all supported locales in cookie" do
conn =
:get
|> conn("/cofe")
|> put_req_cookie(SetLocalePlug.frontend_language_cookie_name(), "zh-Hans,uk,zh-Hant")
|> Conn.put_req_header(
"accept-language",
"ru, fr-CH, fr;q=0.9, en;q=0.8, x-unsupported;q=0.8, *;q=0.5"
)
|> SetLocalePlug.call([])
assert "zh_Hans" == Gettext.get_locale()
assert %{locale: "zh_Hans", locales: ["zh_Hans", "uk", "zh_Hant", "ru", "fr", "en"]} = conn.assigns
end
test "fallback to some variant of the language if the unqualified language is not supported" do test "fallback to some variant of the language if the unqualified language is not supported" do
conn = conn =
:get :get