My navbar is a list of data entries (with some dropdown that are just further lists) and they define what is active or note, built up from the Views themselves so they know that they are being called or not and of which template.
@doc """
Set css class for active link.
"""
@spec css_class(Plug.Conn.t(), String.t(), String.t(), String.t()) :: String.t()
def css_class(conn, path, defaultClass, activeClass \\ "active") do
if path == Phoenix.Controller.current_path(conn) do
defaultClass <> " " <> activeClass
else
defaultClass
end
end
Then in my app.html.eex call the function:
<%= link "Dashboard", to: Routes.user_path(@conn, :show, @current_user), class: css_class(@conn, Routes.user_path(@conn, :show, @current_user), "nav-link") %>
phoenix_html’s content_tag (which is used by link) might not work with attrs (like :class) as iolists since it would call nested_attrs on them. And the “performance win” would probably be completely negligible.
Afaik the biggest performance difference comes from not joining everything into really big binaries and modifying those. I doubt class names fall anywhere close into that category of “big”.
I have improved this to suit my case which having /action_name/slug/etc
@doc """
Sets additional css class when for the current page.
"""
def css_class(conn, path, default_class \\ nil, active_class \\ "active") do
if is_nav_item_actvie?(conn, path) do
"#{default_class} #{active_class}"
else
default_class
end
end
@doc """
Determine if the nav item is active or not.
"""
def is_nav_item_actvie?(conn, path) do
input_action_name = Enum.at(String.split(path, "/"), 1)
current_action_name = List.first(conn.path_info)
IO.inspect(%{c: current_action_name, p: input_action_name})
current_action_name === input_action_name
end