Use correct default language when no Accept-Language is set
Closes #792 Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
cc33ee7ada
commit
ae25cba97a
|
@ -24,21 +24,24 @@ defmodule Mobilizon.Web.Gettext do
|
|||
|
||||
def put_locale(locale) do
|
||||
locale = determine_best_locale(locale)
|
||||
Gettext.put_locale(Mobilizon.Web.Gettext, locale)
|
||||
Gettext.put_locale(__MODULE__, locale)
|
||||
end
|
||||
|
||||
@spec determine_best_locale(String.t()) :: String.t()
|
||||
def determine_best_locale(locale) do
|
||||
locale = String.trim(locale)
|
||||
locales = Gettext.known_locales(Mobilizon.Web.Gettext)
|
||||
locales = Gettext.known_locales(__MODULE__)
|
||||
default = Keyword.get(Mobilizon.Config.instance_config(), :default_language, "en") || "en"
|
||||
|
||||
cond do
|
||||
# Either it matches directly, eg: "en" => "en", "fr" => "fr", "fr_FR" => "fr_FR"
|
||||
# Default if nothing provided
|
||||
locale == "" -> default
|
||||
# Either it matches directly, eg: "en" => "en", "fr" => "fr"
|
||||
locale in locales -> locale
|
||||
# Either the first part matches, "fr_CA" => "fr"
|
||||
split_locale(locale) in locales -> split_locale(locale)
|
||||
# Otherwise set to default
|
||||
true -> Keyword.get(Mobilizon.Config.instance_config(), :default_language, "en") || "en"
|
||||
true -> default
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -9,19 +9,20 @@ defmodule Mobilizon.Web.Plugs.SetLocalePlug do
|
|||
Plug to set locale for Gettext
|
||||
"""
|
||||
import Plug.Conn, only: [get_req_header: 2, assign: 3]
|
||||
alias Mobilizon.Web.Gettext, as: GettextBackend
|
||||
|
||||
def init(_), do: nil
|
||||
|
||||
def call(conn, _) do
|
||||
locale = get_locale_from_header(conn) || Gettext.get_locale()
|
||||
Gettext.put_locale(locale)
|
||||
locale = get_locale_from_header(conn)
|
||||
GettextBackend.put_locale(locale)
|
||||
assign(conn, :locale, locale)
|
||||
end
|
||||
|
||||
defp get_locale_from_header(conn) do
|
||||
conn
|
||||
|> extract_accept_language()
|
||||
|> Enum.find(&supported_locale?/1)
|
||||
|> Enum.find("", &supported_locale?/1)
|
||||
end
|
||||
|
||||
defp extract_accept_language(conn) do
|
||||
|
@ -41,7 +42,7 @@ defmodule Mobilizon.Web.Plugs.SetLocalePlug do
|
|||
end
|
||||
|
||||
defp supported_locale?(locale) do
|
||||
Mobilizon.Web.Gettext
|
||||
GettextBackend
|
||||
|> Gettext.known_locales()
|
||||
|> Enum.member?(locale)
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="<%= Gettext.get_locale() %>">
|
||||
<html lang="<%= @locale %>">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
|
|
|
@ -56,15 +56,18 @@ defmodule Mobilizon.Web.ErrorView do
|
|||
end
|
||||
|
||||
def render("500.html", assigns) do
|
||||
locale =
|
||||
Mobilizon.Config.instance_config()
|
||||
|> Keyword.get(:default_language, "en")
|
||||
|> Gettext.put_locale()
|
||||
|
||||
Gettext.put_locale(locale)
|
||||
|
||||
assigns =
|
||||
assigns
|
||||
|> Map.update(:details, [], & &1)
|
||||
|> Map.put(:instance, Mobilizon.Config.instance_name())
|
||||
|> Map.put(:contact, Mobilizon.Config.contact())
|
||||
|> Map.put(:locale, locale)
|
||||
|
||||
render("500_page.html", assigns)
|
||||
end
|
||||
|
|
|
@ -51,8 +51,29 @@ defmodule Mobilizon.Web.Views.Utils do
|
|||
|> String.replace("<html lang=\"en\">", "<html lang=\"#{locale}\">")
|
||||
end
|
||||
|
||||
@spec get_locale(Conn.t()) :: String.t()
|
||||
def get_locale(%{private: %{cldr_locale: nil}}), do: "en"
|
||||
def get_locale(%{private: %{cldr_locale: %{requested_locale_name: locale}}}), do: locale
|
||||
def get_locale(_), do: "en"
|
||||
@spec get_locale(Plug.Conn.t()) :: String.t()
|
||||
def get_locale(%Plug.Conn{assigns: assigns}) do
|
||||
assigns
|
||||
|> Map.get(:locale)
|
||||
|> check_locale()
|
||||
end
|
||||
|
||||
def get_locale(_), do: default_locale()
|
||||
|
||||
defp check_locale(nil) do
|
||||
default_locale()
|
||||
|> check_locale()
|
||||
end
|
||||
|
||||
defp check_locale("") do
|
||||
check_locale(nil)
|
||||
end
|
||||
|
||||
defp check_locale(locale) when is_binary(locale), do: locale
|
||||
|
||||
defp default_locale do
|
||||
Mobilizon.Config.instance_config()
|
||||
|> Keyword.get(:default_language, "en")
|
||||
|> Kernel.||("en")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -317,6 +317,7 @@ defmodule Mobilizon.GraphQL.Resolvers.UserTest do
|
|||
|
||||
res =
|
||||
conn
|
||||
|> put_req_header("accept-language", "fr")
|
||||
|> AbsintheHelpers.graphql_query(
|
||||
query: @create_user_mutation,
|
||||
variables: @user_creation
|
||||
|
@ -403,6 +404,7 @@ defmodule Mobilizon.GraphQL.Resolvers.UserTest do
|
|||
|
||||
res =
|
||||
conn
|
||||
|> put_req_header("accept-language", "fr")
|
||||
|> AbsintheHelpers.graphql_query(
|
||||
query: @register_person_mutation,
|
||||
variables: Map.put(@user_creation, :email, "random")
|
||||
|
@ -431,6 +433,7 @@ defmodule Mobilizon.GraphQL.Resolvers.UserTest do
|
|||
|
||||
res =
|
||||
conn
|
||||
|> put_req_header("accept-language", "fr")
|
||||
|> AbsintheHelpers.graphql_query(
|
||||
query: @register_person_mutation,
|
||||
variables: @user_creation
|
||||
|
@ -451,6 +454,7 @@ defmodule Mobilizon.GraphQL.Resolvers.UserTest do
|
|||
|
||||
res =
|
||||
conn
|
||||
|> put_req_header("accept-language", "fr")
|
||||
|> AbsintheHelpers.graphql_query(
|
||||
query: @register_person_mutation,
|
||||
variables: Map.put(@user_creation, :preferredUsername, "Myactor")
|
||||
|
|
39
test/web/gettext_test.exs
Normal file
39
test/web/gettext_test.exs
Normal file
|
@ -0,0 +1,39 @@
|
|||
defmodule Mobilizon.Web.GettextTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
alias Mobilizon.Config
|
||||
alias Mobilizon.Web.Gettext, as: GettextBackend
|
||||
|
||||
describe "test determine_best_locale/1" do
|
||||
setup do
|
||||
Config.put([:instance, :default_language], "en")
|
||||
:ok
|
||||
end
|
||||
|
||||
test "with empty string returns the default locale" do
|
||||
assert GettextBackend.determine_best_locale("") == "en"
|
||||
end
|
||||
|
||||
test "with empty string returns the default configured locale" do
|
||||
Config.put([:instance, :default_language], "es")
|
||||
assert GettextBackend.determine_best_locale("") == "es"
|
||||
end
|
||||
|
||||
test "with empty string returns english as a proper fallback if the default configured locale is nil" do
|
||||
Config.put([:instance, :default_language], nil)
|
||||
assert GettextBackend.determine_best_locale("") == "en"
|
||||
end
|
||||
|
||||
test "returns fallback with an unexisting locale" do
|
||||
assert GettextBackend.determine_best_locale("yolo") == "en"
|
||||
end
|
||||
|
||||
test "maps the correct part if the locale has multiple ones" do
|
||||
assert GettextBackend.determine_best_locale("fr_CA") == "fr"
|
||||
end
|
||||
|
||||
test "returns the locale if valid" do
|
||||
assert GettextBackend.determine_best_locale("es") == "es"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,6 +7,7 @@ defmodule Mobilizon.Web.Plugs.SetLocalePlugTest do
|
|||
use ExUnit.Case, async: true
|
||||
use Plug.Test
|
||||
|
||||
alias Mobilizon.Web.Gettext, as: GettextBackend
|
||||
alias Mobilizon.Web.Plugs.SetLocalePlug
|
||||
alias Plug.Conn
|
||||
|
||||
|
@ -17,7 +18,7 @@ defmodule Mobilizon.Web.Plugs.SetLocalePlugTest do
|
|||
|> SetLocalePlug.call([])
|
||||
|
||||
assert "en" == Gettext.get_locale()
|
||||
assert %{locale: "en"} == conn.assigns
|
||||
assert %{locale: ""} == conn.assigns
|
||||
end
|
||||
|
||||
test "use supported locale from `accept-language`" do
|
||||
|
@ -30,7 +31,7 @@ defmodule Mobilizon.Web.Plugs.SetLocalePlugTest do
|
|||
)
|
||||
|> SetLocalePlug.call([])
|
||||
|
||||
assert "ru" == Gettext.get_locale()
|
||||
assert "ru" == Gettext.get_locale(GettextBackend)
|
||||
assert %{locale: "ru"} == conn.assigns
|
||||
end
|
||||
|
||||
|
@ -41,7 +42,7 @@ defmodule Mobilizon.Web.Plugs.SetLocalePlugTest do
|
|||
|> Conn.put_req_header("accept-language", "tlh")
|
||||
|> SetLocalePlug.call([])
|
||||
|
||||
assert "en" == Gettext.get_locale()
|
||||
assert %{locale: "en"} == conn.assigns
|
||||
assert "en" == Gettext.get_locale(GettextBackend)
|
||||
assert %{locale: ""} == conn.assigns
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue