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 @@ 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