forked from AkkomaGang/akkoma
Support multiple locales from userLanguage cookie
This commit is contained in:
parent
7ea330b4fe
commit
aca11fb70e
3 changed files with 39 additions and 17 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue