View Source PlugLocale.WebBrowser (plug_locale v0.1.0)
Puts locale into assigns storage for Web browser environment.
The most common way of specifying the desired locale is via the URL. In general, there're three methods to do that:
- via domain name -
https://<locale>.example.com, such as:https://en.example.com/welcomehttps://zh.example.com/welcome
- via path -
https://example.com/<locale>, such as:https://example.com/en/welcomehttps://example.com/zh/welcome
- via querystring -
https://example.com?locale=<locale>, such as:https://example.com/welcome?locale=enhttps://example.com/welcome?locale=zh
Personally, I think method 2 is better,compared to the other two methods:
- method 1 is tedious for deployment.
- URLs generated by method 3 look very ugly and unprofessional.
Because of that, this plug will stick on method 2.
Usage
First, we need to integrate this plug with other libraries, or this plug
is useless. All you need is to construct a plug pipeline through
Plug.Builder. For example:
defmodule DemoWeb.PlugWebBrowserLocalization do
use Plug.Builder
plug PlugLocale.WebBrowser,
default_locale: "en",
locales: ["en", "zh"],
route_identifier: :locale,
assign_key: :locale
plug :set_locale
def set_locale(conn, _opts) do
if locale conn.assigns[:locale] do
# integrate with gettext
Gettext.put_locale(locale)
end
conn
end
endThen, use it in router (following one is a Phoenix router, but Plug.Router
is supported, too):
defmodule DemoWeb.Router do
use DemoWeb, :router
pipeline :browser do
plug :accepts, ["html"]
# ...
plug DemoWeb.PlugWebBrowserLocalization
# ...
end
scope "/", DemoWeb do
pipe_through :browser
get "/", PageController, :index
# ...
end
# Why using :locale?
# Because it is specified by `:route_identifier` option.
scope "/:locale", DemoWeb do
pipe_through :browser
get "/", PageController, :index
# ...
end
endOptions
:default_locale- the default locale.:locales- all the supported locales. Default to[].:sanitize_locale- a function for sanitizing extracted or detected locales. Default to&PlugLocale.Sanitizer.sanitize/1which does nothing. SeePlugLocale.Sanitizerfor more details.:route_identifier- the part for identifying locale in route. Default to:locale.:assign_key- the key for putting value intoassignsstorage. Default to the value of:route_identifieroption.:cookie_key- the key for reading locale from cookie. Default to"preferred_locale".
How it works?
This plug will try to:
- extract locale from URL, and check if the locale is supported:
- If it succeeds, put locale into
assignsstorage。 - If it fails, jump to step 2.
- If it succeeds, put locale into
- detect locale from Web browser environment, then redirect to the path corresponding to detected locale.
Extract locale from URL
For example, the locale extracted from https://example.com/en/welcome
is en.
Detect locale from Web browser environment
Local is detected from multiple places:
- cookie (whose key is specified by
:cookie_keyoption) - HTTP request header -
referer - HTTP request header -
accept-language - default locale (which is specified by
:default_localeoption)
Examples
When:
:default_localeoption is set to"en":localesoption is set to["en", "zh"]
For users in an English-speaking environment:
https://example.com/enwill be responded directly.https://example.com/will be redirected tohttps://example.com/en.https://example.com/pathwill be redirected tohttps://example.com/en/path.https://example.com/unknownwill be redirected tohttps://example.com/en.- ...
For users in an Chinese-speaking environment:
https://example.com/zhwill be responded directly.https://example.com/will be redirected tohttps://example.com/zh.https://example.com/pathwill be redirected tohttps://example.com/zh/path.https://example.com/unknownwill be redirected tohttps://example.com/zh.- ...