Changeset View
Changeset View
Standalone View
Standalone View
larus/lib/larus/plug/locale.ex
- This file was added.
defmodule Larus.Plug.Locale do | |||||
require Logger | |||||
import Plug.Conn | |||||
def init(default) do | |||||
default | |||||
end | |||||
def call(conn, default) do | |||||
locale = conn.params["locale"] | |||||
if locale in Larus.Gettext.supported_locales do | |||||
conn |> assign_locale! locale | |||||
else | |||||
locale = List.first(extract_locale(conn)) || default | |||||
conn |> assign_locale! locale | |||||
end | |||||
end | |||||
defp assign_locale!(conn, value) do | |||||
Logger.debug "Assigning locale #{inspect value}" | |||||
Gettext.put_locale(Larus.Gettext, value) | |||||
conn | |||||
|> assign(:locale, value) | |||||
end | |||||
defp extract_locale(conn) do | |||||
if Blank.present? conn.params["locale"] do | |||||
[conn.params["locale"] | extract_accept_language(conn)] | |||||
else | |||||
extract_accept_language(conn) | |||||
end | |||||
# Filter for only known locales | |||||
|> Enum.filter(fn locale -> Enum.member?(Larus.Gettext.supported_locales, locale) end) | |||||
end | |||||
defp extract_accept_language(conn) do | |||||
case conn |> get_req_header("accept-language") do | |||||
[value|_] -> | |||||
value | |||||
|> String.split(",") | |||||
|> Enum.map(&parse_language_option/1) | |||||
|> Enum.sort(&(&1.quality > &2.quality)) | |||||
|> Enum.map(&(&1.tag)) | |||||
_ -> | |||||
[] | |||||
end | |||||
end | |||||
defp parse_language_option(string) do | |||||
captures = ~r/^(?<tag>[\w\-]+)(?:;q=(?<quality>[\d\.]+))?$/i | |||||
|> Regex.named_captures(string) | |||||
quality = case Float.parse(captures["quality"] || "1.0") do | |||||
{val, _} -> val | |||||
_ -> 1.0 | |||||
end | |||||
%{tag: captures["tag"], quality: quality} | |||||
end | |||||
end |