Fresh repository history for elektrine/tarakan hosted at https://git.elektrine.com/elektrine/tarakan.
48 lines
1.7 KiB
Elixir
48 lines
1.7 KiB
Elixir
defmodule TarakanWeb.CurrentPath do
|
|
@moduledoc """
|
|
Makes the request path available to the layout as `@current_path`.
|
|
|
|
The navigation highlight used to be applied by JavaScript after render, which
|
|
had two problems. Every page painted with nothing highlighted and lit up a
|
|
frame later, and dead controller routes like `/pricing` have no LiveSocket at
|
|
all, so the hook never ran there and the tab could never highlight itself.
|
|
|
|
Both go away if the server decides. This supplies the path for the two kinds
|
|
of page: a plug for controller-rendered views, and an `on_mount` hook that
|
|
re-reads it on every `handle_params` so live navigation stays correct.
|
|
"""
|
|
|
|
import Phoenix.Component, only: [assign: 3]
|
|
import Phoenix.LiveView, only: [attach_hook: 4]
|
|
|
|
@doc "Plug for controller-rendered pages."
|
|
def init(opts), do: opts
|
|
|
|
def call(conn, _opts), do: Plug.Conn.assign(conn, :current_path, conn.request_path)
|
|
|
|
@doc "`on_mount` hook for live sessions."
|
|
def on_mount(:default, _params, _session, socket) do
|
|
{:cont,
|
|
socket
|
|
|> assign(:current_path, nil)
|
|
|> attach_hook(:current_path, :handle_params, &put_current_path/3)}
|
|
end
|
|
|
|
defp put_current_path(_params, uri, socket) do
|
|
{:cont, assign(socket, :current_path, URI.parse(uri).path)}
|
|
end
|
|
|
|
@doc """
|
|
Whether `path` is the section the visitor is currently in.
|
|
|
|
A section owns its subtree, so `/jobs` stays lit on `/jobs/12`. The root is
|
|
matched exactly, otherwise it would own every page on the site.
|
|
"""
|
|
def active?(nil, _path), do: false
|
|
def active?(_current, nil), do: false
|
|
def active?(current, "/"), do: current == "/"
|
|
|
|
def active?(current, path) do
|
|
current == path or String.starts_with?(current, path <> "/")
|
|
end
|
|
end
|