if Code.ensure_loaded?(Plug) do defmodule Cldr.Plug.AcceptLanguage do @moduledoc """ Parses the accept-language header if one is available and sets `conn.private[:cldr_locale]` accordingly. The locale can be later retrieved by `Cldr.Plug.AcceptLanguage.get_cldr_locale/1` ## Options * `:cldr_backend` is any backend module. The default is `Cldr.default_backend/0`. If no `:cldr_backend` option is provided and no default backend is configured then an exception will be raised. * `:no_match_log_level` determines the logging level for the case when no matching locale is configured to meet the users request. The default is `:warn`. If set to `nil` then no logging is performed. ## Example # Using a specific backend to validate # and match locales plug Cldr.Plug.AcceptLanguage, cldr_backend: MyApp.Cldr # Using the default backend to validate # and match locales plug Cldr.Plug.AcceptLanguage """ import Plug.Conn require Logger @language_header "accept-language" @default_log_level :warn @doc false def init(options \\ []) do backend = Keyword.get_lazy(options, :cldr_backend, &Cldr.default_backend!/0) log_level = Keyword.get(options, :no_match_log_level, @default_log_level) %{backend: backend, 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, :cldr_locale, best_match(accept_language, options)) [accept_language | _] -> put_private(conn, :cldr_locale, best_match(accept_language, options)) [] -> put_private(conn, :cldr_locale, nil) end end @doc """ Returns the locale which is the best match for the provided accept-language header """ def best_match(nil, _) do nil end def best_match(accept_language, options) do case Cldr.AcceptLanguage.best_match(accept_language, options.backend) do {:ok, locale} -> locale {:error, {Cldr.NoMatchingLocale = exception, reason}} -> if options.log_level, do: Logger.log(options.log_level, "#{inspect(exception)}: #{reason}") nil {:error, {exception, reason}} -> Logger.warn("#{inspect(exception)}: #{reason}") nil end end @doc """ Return the locale set by `Cldr.Plug.AcceptLanguage` """ def get_cldr_locale(conn) do conn.private[:cldr_locale] end end end