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
|
def put_locale(locale) do
|
||||||
locale = determine_best_locale(locale)
|
locale = determine_best_locale(locale)
|
||||||
Gettext.put_locale(Mobilizon.Web.Gettext, locale)
|
Gettext.put_locale(__MODULE__, locale)
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec determine_best_locale(String.t()) :: String.t()
|
@spec determine_best_locale(String.t()) :: String.t()
|
||||||
def determine_best_locale(locale) do
|
def determine_best_locale(locale) do
|
||||||
locale = String.trim(locale)
|
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
|
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
|
locale in locales -> locale
|
||||||
# Either the first part matches, "fr_CA" => "fr"
|
# Either the first part matches, "fr_CA" => "fr"
|
||||||
split_locale(locale) in locales -> split_locale(locale)
|
split_locale(locale) in locales -> split_locale(locale)
|
||||||
# Otherwise set to default
|
# Otherwise set to default
|
||||||
true -> Keyword.get(Mobilizon.Config.instance_config(), :default_language, "en") || "en"
|
true -> default
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -9,19 +9,20 @@ defmodule Mobilizon.Web.Plugs.SetLocalePlug do
|
||||||
Plug to set locale for Gettext
|
Plug to set locale for Gettext
|
||||||
"""
|
"""
|
||||||
import Plug.Conn, only: [get_req_header: 2, assign: 3]
|
import Plug.Conn, only: [get_req_header: 2, assign: 3]
|
||||||
|
alias Mobilizon.Web.Gettext, as: GettextBackend
|
||||||
|
|
||||||
def init(_), do: nil
|
def init(_), do: nil
|
||||||
|
|
||||||
def call(conn, _) do
|
def call(conn, _) do
|
||||||
locale = get_locale_from_header(conn) || Gettext.get_locale()
|
locale = get_locale_from_header(conn)
|
||||||
Gettext.put_locale(locale)
|
GettextBackend.put_locale(locale)
|
||||||
assign(conn, :locale, locale)
|
assign(conn, :locale, locale)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp get_locale_from_header(conn) do
|
defp get_locale_from_header(conn) do
|
||||||
conn
|
conn
|
||||||
|> extract_accept_language()
|
|> extract_accept_language()
|
||||||
|> Enum.find(&supported_locale?/1)
|
|> Enum.find("", &supported_locale?/1)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp extract_accept_language(conn) do
|
defp extract_accept_language(conn) do
|
||||||
|
@ -41,7 +42,7 @@ defmodule Mobilizon.Web.Plugs.SetLocalePlug do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp supported_locale?(locale) do
|
defp supported_locale?(locale) do
|
||||||
Mobilizon.Web.Gettext
|
GettextBackend
|
||||||
|> Gettext.known_locales()
|
|> Gettext.known_locales()
|
||||||
|> Enum.member?(locale)
|
|> Enum.member?(locale)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="<%= Gettext.get_locale() %>">
|
<html lang="<%= @locale %>">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
|
@ -56,15 +56,18 @@ defmodule Mobilizon.Web.ErrorView do
|
||||||
end
|
end
|
||||||
|
|
||||||
def render("500.html", assigns) do
|
def render("500.html", assigns) do
|
||||||
|
locale =
|
||||||
Mobilizon.Config.instance_config()
|
Mobilizon.Config.instance_config()
|
||||||
|> Keyword.get(:default_language, "en")
|
|> Keyword.get(:default_language, "en")
|
||||||
|> Gettext.put_locale()
|
|
||||||
|
Gettext.put_locale(locale)
|
||||||
|
|
||||||
assigns =
|
assigns =
|
||||||
assigns
|
assigns
|
||||||
|> Map.update(:details, [], & &1)
|
|> Map.update(:details, [], & &1)
|
||||||
|> Map.put(:instance, Mobilizon.Config.instance_name())
|
|> Map.put(:instance, Mobilizon.Config.instance_name())
|
||||||
|> Map.put(:contact, Mobilizon.Config.contact())
|
|> Map.put(:contact, Mobilizon.Config.contact())
|
||||||
|
|> Map.put(:locale, locale)
|
||||||
|
|
||||||
render("500_page.html", assigns)
|
render("500_page.html", assigns)
|
||||||
end
|
end
|
||||||
|
|
|
@ -51,8 +51,29 @@ defmodule Mobilizon.Web.Views.Utils do
|
||||||
|> String.replace("<html lang=\"en\">", "<html lang=\"#{locale}\">")
|
|> String.replace("<html lang=\"en\">", "<html lang=\"#{locale}\">")
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec get_locale(Conn.t()) :: String.t()
|
@spec get_locale(Plug.Conn.t()) :: String.t()
|
||||||
def get_locale(%{private: %{cldr_locale: nil}}), do: "en"
|
def get_locale(%Plug.Conn{assigns: assigns}) do
|
||||||
def get_locale(%{private: %{cldr_locale: %{requested_locale_name: locale}}}), do: locale
|
assigns
|
||||||
def get_locale(_), do: "en"
|
|> 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
|
end
|
||||||
|
|
|
@ -317,6 +317,7 @@ defmodule Mobilizon.GraphQL.Resolvers.UserTest do
|
||||||
|
|
||||||
res =
|
res =
|
||||||
conn
|
conn
|
||||||
|
|> put_req_header("accept-language", "fr")
|
||||||
|> AbsintheHelpers.graphql_query(
|
|> AbsintheHelpers.graphql_query(
|
||||||
query: @create_user_mutation,
|
query: @create_user_mutation,
|
||||||
variables: @user_creation
|
variables: @user_creation
|
||||||
|
@ -403,6 +404,7 @@ defmodule Mobilizon.GraphQL.Resolvers.UserTest do
|
||||||
|
|
||||||
res =
|
res =
|
||||||
conn
|
conn
|
||||||
|
|> put_req_header("accept-language", "fr")
|
||||||
|> AbsintheHelpers.graphql_query(
|
|> AbsintheHelpers.graphql_query(
|
||||||
query: @register_person_mutation,
|
query: @register_person_mutation,
|
||||||
variables: Map.put(@user_creation, :email, "random")
|
variables: Map.put(@user_creation, :email, "random")
|
||||||
|
@ -431,6 +433,7 @@ defmodule Mobilizon.GraphQL.Resolvers.UserTest do
|
||||||
|
|
||||||
res =
|
res =
|
||||||
conn
|
conn
|
||||||
|
|> put_req_header("accept-language", "fr")
|
||||||
|> AbsintheHelpers.graphql_query(
|
|> AbsintheHelpers.graphql_query(
|
||||||
query: @register_person_mutation,
|
query: @register_person_mutation,
|
||||||
variables: @user_creation
|
variables: @user_creation
|
||||||
|
@ -451,6 +454,7 @@ defmodule Mobilizon.GraphQL.Resolvers.UserTest do
|
||||||
|
|
||||||
res =
|
res =
|
||||||
conn
|
conn
|
||||||
|
|> put_req_header("accept-language", "fr")
|
||||||
|> AbsintheHelpers.graphql_query(
|
|> AbsintheHelpers.graphql_query(
|
||||||
query: @register_person_mutation,
|
query: @register_person_mutation,
|
||||||
variables: Map.put(@user_creation, :preferredUsername, "Myactor")
|
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 ExUnit.Case, async: true
|
||||||
use Plug.Test
|
use Plug.Test
|
||||||
|
|
||||||
|
alias Mobilizon.Web.Gettext, as: GettextBackend
|
||||||
alias Mobilizon.Web.Plugs.SetLocalePlug
|
alias Mobilizon.Web.Plugs.SetLocalePlug
|
||||||
alias Plug.Conn
|
alias Plug.Conn
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ defmodule Mobilizon.Web.Plugs.SetLocalePlugTest do
|
||||||
|> SetLocalePlug.call([])
|
|> SetLocalePlug.call([])
|
||||||
|
|
||||||
assert "en" == Gettext.get_locale()
|
assert "en" == Gettext.get_locale()
|
||||||
assert %{locale: "en"} == conn.assigns
|
assert %{locale: ""} == conn.assigns
|
||||||
end
|
end
|
||||||
|
|
||||||
test "use supported locale from `accept-language`" do
|
test "use supported locale from `accept-language`" do
|
||||||
|
@ -30,7 +31,7 @@ defmodule Mobilizon.Web.Plugs.SetLocalePlugTest do
|
||||||
)
|
)
|
||||||
|> SetLocalePlug.call([])
|
|> SetLocalePlug.call([])
|
||||||
|
|
||||||
assert "ru" == Gettext.get_locale()
|
assert "ru" == Gettext.get_locale(GettextBackend)
|
||||||
assert %{locale: "ru"} == conn.assigns
|
assert %{locale: "ru"} == conn.assigns
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ defmodule Mobilizon.Web.Plugs.SetLocalePlugTest do
|
||||||
|> Conn.put_req_header("accept-language", "tlh")
|
|> Conn.put_req_header("accept-language", "tlh")
|
||||||
|> SetLocalePlug.call([])
|
|> SetLocalePlug.call([])
|
||||||
|
|
||||||
assert "en" == Gettext.get_locale()
|
assert "en" == Gettext.get_locale(GettextBackend)
|
||||||
assert %{locale: "en"} == conn.assigns
|
assert %{locale: ""} == conn.assigns
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue