Support multiple locales from userLanguage cookie

This commit is contained in:
Tusooa Zhu 2022-03-03 02:31:36 -05:00 committed by FloatingGhost
parent fa95bc8725
commit 07bd35227a
3 changed files with 39 additions and 17 deletions

View file

@ -37,7 +37,7 @@ def language_tag 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 @@ def supports_locale?(locale) 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 @@ defp get_locales_from_header(conn) 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 @@ defp extract_frontend_language(conn) do
[] []
fe_lang -> fe_lang ->
[fe_lang] String.split(fe_lang, ",")
|> ensure_language_fallbacks()
end end
end end
@ -67,7 +67,6 @@ defp extract_accept_language(conn) 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 @@ defp parse_language_option(string) 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 @@ test "it assigns all supported locales" 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