Current section
Files
Jump to
Current section
Files
lib/localize/plug/accept_language.ex
defmodule Localize.Plug.AcceptLanguage do
@moduledoc """
Standalone plug that parses the `Accept-Language` header and sets `conn.private[:localize_locale]` to the
best matching locale.
The locale can be later retrieved by `Localize.Plug.AcceptLanguage.get_locale/1`. This plug is useful
when you only need accept-language parsing without the full locale discovery pipeline of `Localize.Plug.PutLocale`.
### Options
* `:no_match_log_level` determines the logging level for the case when no matching locale is configured to meet the user's
request. The default is `:warning`. If set to `nil` then no logging is performed.
### Examples
plug Localize.Plug.AcceptLanguage
"""
import Plug.Conn
require Logger
@language_header "accept-language"
@default_log_level :warning
@doc false
def init(options \\ []) do
log_level = Keyword.get(options, :no_match_log_level, @default_log_level)
%{log_level: log_level}
end
@doc false
def call(conn, options) do
case get_req_header(conn, @language_header) do
[accept_language | _] ->
put_private(conn, :localize_locale, best_match(accept_language, options))
[] ->
put_private(conn, :localize_locale, nil)
end
end
@doc """
Returns the best matching locale for the provided accept-language header value.
### Arguments
* `accept_language` is an accept-language header string or `nil`.
* `options` is the plug options map containing `:log_level`.
### Returns
* A `t:Localize.LanguageTag.t/0` or `nil`.
"""
def best_match(nil, _options) do
nil
end
def best_match(accept_language, options) do
case Localize.AcceptLanguage.best_match(accept_language) do
{:ok, locale} ->
locale
{:error, %Localize.UnknownLocaleError{} = exception} ->
if options.log_level do
Logger.log(
options.log_level,
"Localize.Plug.AcceptLanguage: no matching locale found " <>
"for accept-language header #{inspect(accept_language)}. " <>
Exception.message(exception)
)
end
nil
{:error, %{__exception__: true} = exception} ->
Logger.warning(
"Localize.Plug.AcceptLanguage: error parsing accept-language header " <>
"#{inspect(accept_language)}. #{Exception.message(exception)}"
)
nil
end
end
@doc """
Returns the locale set by `Localize.Plug.AcceptLanguage`.
### Arguments
* `conn` is a `t:Plug.Conn.t/0`.
### Returns
* A `t:Localize.LanguageTag.t/0` or `nil`.
"""
def get_locale(conn) do
conn.private[:localize_locale]
end
end