Kin
Redirect on a default language?
How do I make my default language Hungarian not being present in the URL? Only /en/rolunk but /rolunk when it’s in Hungarian (by default). I guess in router.ex file I have to add some condition in scope “/” part. But I have no idea how. How to do that?
I would like to redirect all /hu/* stuff to /* as well.
But /en/* to stay as /en/*.
Right now my router files looks like this:
defmodule HelloWeb.Router do
use HelloWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, html: {HelloWeb.Layouts, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", HelloWeb do
pipe_through :browser
get "/", PageController, :home
end
# Other scopes may use custom stacks.
# scope "/api", HelloWeb do
# pipe_through :api
# end
# Enable LiveDashboard and Swoosh mailbox preview in development
if Application.compile_env(:hello, :dev_routes) do
# If you want to use the LiveDashboard in production, you should put
# it behind authentication and allow only admins to access it.
# If your application does not have an admins-only section yet,
# you can use Plug.BasicAuth to set up some basic authentication
# as long as you are also using SSL (which you should anyway).
import Phoenix.LiveDashboard.Router
scope "/dev" do
pipe_through :browser
live_dashboard "/dashboard", metrics: HelloWeb.Telemetry
forward "/mailbox", Plug.Swoosh.MailboxPreview
end
end
end
Most Liked
zaljir
For others still searching… A simple possible solution is something like this:
scope "/en", MyWeb do
pipe_through :browser
live_session :set_locale_en, on_mount: {MyWeb.SetLocale, :en} do
live "/", DocumentLive, :home
live "/:parent_slug/:slug", DocumentLive, :document
live "/:slug", DocumentLive, :document
end
end
scope "/", MyWeb do
pipe_through :browser
live_session :set_locale_nl, on_mount: {MyWeb.SetLocale, :nl} do
live "/nl/*rest", DocumentLive, :redirect
live "/", DocumentLive, :home
live "/:parent_slug/:slug", DocumentLive, :document
live "/:slug", DocumentLive, :document
end
end
Just define a scope for all languages and for the main language redirect to the URL without locale prefix.
MyWeb.SetLocale just assigns the locale as variable to the live view.
This can be simplified even further with macros for example, but you get the idea.
gdub01
I like zaljir’s approach! I also just finished doing something like this and used Kip’s ex_cldr_plugs | Hex and ex_cldr_routes | Hex.
I wanted to try to get the user’s accept language header first and default to cldr’s default if not found.
Then I wanted to force all users to have a locale in the route.. then only respect the route’s locale after that.
Router looks like:
scope "/", MyAppWeb do
pipe_through :browser
get "/", PageController, :redirect_to_default_lang
localize do
get "/#{locale}", PageController, :home
live "/#{locale}/videos", VideoLive.Index, :index
live "/#{locale}/videos/new", VideoLive.Index, :new
live "/#{locale}/videos/:id/edit", VideoLive.Index, :edit
live "/#{locale}/videos/:id", VideoLive.Show, :show
live "/#{locale}/videos/:id/show/edit", VideoLive.Show, :edit
end
with this in the pipeline:
plug Cldr.Plug.PutLocale,
apps: [:cldr, :gettext],
from: [:route, :query, :path, :accept_language, :session],
gettext: MyAppWeb.Gettext,
cldr: MyApp.Cldr
So the plug finds the best language for the user based on route/accept language header, etc.
If the user visits the main page, it hits this redirect controller to get the best language and sends them off to the correct route ie. “/fr”. All navigation links after that expect a locale.
defmodule MyAppWeb.PageController do
use MyAppWeb, :controller
def redirect_to_default_lang(conn, _params) do
redirect(conn, to: "/#{MyApp.Cldr.get_locale().cldr_locale_name}")
end
end
and this puts the locale in the session:
defmodule MyAppWeb.RestoreLocale do
def on_mount(:default, _, %{"cldr_locale" => cldr_locale}, socket) do
MyApp.Cldr.put_locale(cldr_locale)
Gettext.put_locale(
MyAppWeb.Gettext,
Atom.to_string(MyApp.Cldr.get_locale().cldr_locale_name)
)
{:cont, socket}
end
def on_mount(:default, _params, _session, socket), do: {:cont, socket}
end
abat
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









