Phoenix integration for the Localize library providing plugs for locale discovery, compile-time route localization, and HTML form helpers for localized data.
Features
Locale Discovery — detect the user's locale from the accept-language header, query parameters, URL path, session, cookies, hostname TLD, or custom functions.
Session Persistence — store the discovered locale in the session for subsequent requests and LiveView connections.
Compile-time Route Localization — translate route path segments using Gettext at compile time and generate localized routes for each configured locale.
Verified Localized Routes — the
~qsigil provides compile-time verified localized routes that dispatch to the correct translated path based on the current locale.hreflang Annotations — render validated
rel="alternate"hreflanglink sets from the generated route helpers, from verified routes, or from any map of locale to URL.HTML Form Helpers — generate
<select>tags and option lists for currencies, territories, territory subdivisions, locales, units of measure, and months with localized display names.
Installation
Add localize_web to your list of dependencies in mix.exs:
def deps do
[
{:localize_web, "~> 1.0"}
]
endQuick Start
Locale Discovery
Add the locale plugs to your Phoenix browser pipeline after fetch_session:
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug Localize.Plug.PutLocale, gettext: MyApp.Gettext
plug Localize.Plug.PutSession
endLocalize.Plug.PutLocale reads the :session source with
Plug.Conn.get_session/2, so fetch_session must run first. If :cookie is
used outside a browser/session pipeline, fetch cookies before PutLocale;
fetch_session already does that in the browser pipeline.
LiveView Support
Restore the locale in your LiveView on_mount callback:
def on_mount(:default, _params, session, socket) do
_ = Localize.Plug.put_locale_from_session(session, gettext: MyApp.Gettext)
{:cont, socket}
endThe result is not matched on: a first visit has no locale in the session, and the process keeps the default locale.
Define localized live routes with localize_live_session/3 rather than live_session/3. It puts each locale's routes into their own live session, so a live navigation to another locale reloads the page in that locale:
localize_live_session :default, on_mount: [MyAppWeb.LocaleLive] do
localize do
live "/#{locale}/dashboard", DashboardLive
end
endLocalized Routes
Configure your router with localized routes:
defmodule MyApp.Router do
use Phoenix.Router
use Localize.Routes, gettext: MyApp.Gettext
localize do
get "/pages/:page", PageController, :show
resources "/users", UserController
end
endProvide translations in priv/gettext/{locale}/LC_MESSAGES/routes.po for each path segment.
Verified Localized Routes
Use the ~q sigil for compile-time verified localized paths:
use Localize.VerifiedRoutes,
router: MyApp.Router,
endpoint: MyApp.Endpoint,
gettext: MyApp.Gettext
# In templates:
~q"/users"HTML Helpers
Generate localized select tags in your templates:
iex> Localize.HTML.Territory.select(:my_form, :territory, selected: :AU)
iex> Localize.HTML.Currency.select(:my_form, :currency, selected: :USD)
iex> Localize.HTML.Locale.select(:my_form, :locale, selected: "en")Documentation
Full documentation is available on HexDocs.
Acknowledgements
Attribution
The localized routing in this library is based on ex_cldr_routes which was inspired by the work originally done by Bart Otten on PhxAltRoutes — which has evolved to the much enhanced Routex. Users seeking a more comprehensive and extensible localized routing solution should consider Routex as an alternative to Localize.Routes.