defmodule MvWeb.Plugs.SetLocale do @moduledoc """ Plug to set the locale for the application. Defaults to German if no locale is specified. """ import Plug.Conn @supported_locales ["de", "en"] @default_locale "de" def init(_), do: nil def call(conn, _) do case fetch_locale(conn) do nil -> # Set default locale if none found Gettext.put_locale(MvWeb.Gettext, @default_locale) persist(@default_locale, conn) locale -> # Set and persist locale IO.inspect(locale, label: "locale") Gettext.put_locale(MvWeb.Gettext, locale) |> persist(conn) end end defp fetch_locale(conn) do conn.params["locale"] || get_session(conn, :locale) || parse_accept_language(conn) || @default_locale end defp parse_accept_language(conn) do case get_req_header(conn, "accept-language") do [accept_language | _] -> parse_accept_language_header(accept_language) _ -> nil end end defp parse_accept_language_header(accept_language) do accept_language |> String.split(",") |> Enum.map(&parse_language_tag/1) |> Enum.find(&(&1 in @supported_locales)) end defp parse_language_tag(tag) do tag |> String.trim() |> String.split(";") |> List.first() |> String.split("-") |> List.first() |> String.downcase() end defp persist(locale, conn) do IO.inspect(locale, label: "persist_locale") # Ensure locale is a string before setting cookie locale_string = to_string(locale) put_session(conn, :locale, locale_string) |> put_resp_cookie("locale", locale_string) end end