defmodule Cldr.Plug do @moduledoc """ Functions to support setting the locale for Cldr and/or Gettext from the session. """ @type application :: :cldr | :gettext @type applications :: [application] @session_key Cldr.Plug.PutLocale.session_key() @doc """ Puts the locale from the session into the current process for `Cldr` and/or `Gettext`. This function is useful to place in the `on_mount` callback for a LiveView. ## Arguments * `session` is any map, typically the map returned as part of the `conn` of a Phoenix or Plug request, A `session` is passed as the third parameter to the `on_mount` callback of a LiveView request. * `applications` is a list of applications for which the locale may be set. The valid options are `:cldr` and `:gettext`. The default is `[:cldr, :gettext]` ## Returns * `{:ok, locale}` or * `{:error, {exception, reason}}` ## Example => Cldr.Plug.put_locale_from_session(session) => Cldr.Plug.put_locale_from_session(session, [:cldr]) => Cldr.Plug.put_locale_from_session(session, [:cldr, :gettext]) # In a LiveView def on_mount(:default, _params, session, socket) do {:ok, locale} = Cldr.Plug.put_locale_from_session(session) end """ @spec put_locale_from_session(map, applications) :: {:ok, Cldr.LanguageTag.t()} | {:error, {module(), String.t()}} def put_locale_from_session(locale, applications \\ [:cldr, :gettext]) def put_locale_from_session(%{@session_key => locale}, applications) do with {:ok, locale} <- Cldr.validate_locale(locale) do Enum.reduce_while(applications, nil, fn :cldr, _acc -> {:cont, Cldr.put_locale(locale)} :gettext, _acc -> if locale.gettext_locale_name do gettext_backend = locale.backend.__cldr__(:config).gettext Gettext.put_locale(gettext_backend, locale.gettext_locale_name) {:cont, {:ok, locale}} else {:halt, {:error, {Cldr.UnknownLocaleError, "No gettext locale defined for #{inspect(locale)}"}}} end other, _acc -> raise ArgumentError, "Invalid application passed to Cldr.Plug.put_locale_from_session/2. " <> "Valid applications are :cldr and :gettext. Found #{inspect(other)}" end) end end def put_locale_from_session(_session, _options) do {:error, {Cldr.UnknownLocaleError, "No locale was found in the session"}} end end