I am working on web app with 2 languages (English, Arabic), it has two directions of course (RTL, LTR). I would like when the user click on the flag button (flags to represent languages), the page reload with the newly selected locale, for example he/she reading some post, and he clicked “English” then the same post page reloaded in English language. I implemented this with lifecycle hooks
but I don’t like the implementation because I have a lot of views, I used case do
to check the current socket.view
and check for the action also in socket.assigns.live_action
but the logic became sooo long. I know in Phoenix there is current_path/2
function but it works only inside controllers for conn
but not for socket
.
here is what I used and how I implemented and hope someone will direct me to the right way of implementing this.
defmodule AhramSchoolWeb.Platforms.AdminPlatform do
import Phoenix.LiveView
import Gettext, only: [with_locale: 2]
import AhramSchoolWeb.Gettext, only: [pgettext: 2]
alias AhramSchoolWeb.Router.Helpers, as: Routes
def on_mount(:default, _params, _session, socket) do
{:cont,
attach_hook(socket, :current_page, :handle_params, &set_active_tab_and_locale_route/3)}
end
defp set_active_tab_and_locale_route(params, _url, socket) do
current_locale = socket.assigns.locale
locale = (current_locale == "ar" && "en") || "ar"
{active_tab, route} =
with_locale(current_locale, fn ->
case {socket.view, socket.assigns.live_action} do
{AcademicsLive, :index} ->
{pgettext("sidebar-admin", "Manage"),
Routes.academics_path(socket, :index, locale: locale)}
{DashboardLive, :index} ->
{pgettext("sidebar-admin", "Dashboard"),
Routes.admin_dashboard_path(socket, :index, locale: locale)}
{AdmissionLive.Index, :index} ->
{pgettext("sidebar-admin", "Applicants"),
Routes.admission_index_path(socket, :index, locale: locale)}
{AdmissionLive.Show, :show} ->
{pgettext("sidebar-admin", "Applicants"),
Routes.admission_show_path(socket, :show, params["id"], locale: locale)}
{CandidateLive.Index, :index} ->
{pgettext("sidebar-admin", "Candidates"),
Routes.candidate_index_path(socket, :index, locale: locale)}
{CandidateLive.Show, action} when action in [:show, :add_note] ->
{pgettext("sidebar-admin", "Candidates"),
Routes.candidate_show_path(socket, action, params["id"], locale: locale)}
{CandidateLive.Show, _} ->
{pgettext("sidebar-admin", "Candidates"),
Routes.candidate_show_path(socket, :show, params["id"], locale: locale)}
.
.
.
.
{_, _} ->
{nil, Routes.admin_dashboard_path(socket, :index, locale: locale)}
end
end)
{:cont,
socket
|> assign(locale_route: route)
|> assign(active_tab: active_tab)}
end
So in the function above, I check the current view, current action and if any params, also I return Label to determine the current page label to be highlighted in Sidebar, also the web app has front website and back dashboard so I have REALLY a lot of views. Above I am showing only views for back dashboard.
and in router.ex
file
live_session :admin, on_mount: AdminPlatform do
scope "/admin/dashboard", AhramSchoolWeb.Platforms.Admin do
pipe_through :browser
live("/", DashboardLive, :index, as: :admin_dashboard)
..............
........
end
end