Примените класс CSS к элементу, если текущая страница в Phoenix
В настоящее время я хочу добавить класс CSS, если активна страница. Каков наилучший способ сделать это сейчас в Финиксе? Есть ли помощник для этого случая?
def active(option, conn) do
if option == conn.request_path do
" class=\"active\""
else
""
end
end
В шаблоне:
<%= "contact" |> active(@conn) |> raw %>
Ответы
Ответ 1
Мы будем использовать conn.path_info
, который возвращает текущий путь как список строк вместо conn.request_path
. Мы могли бы использовать это, чтобы попасть в наш помощник active_class
.
def active_class(conn, path) do
current_path = Path.join(["/" | conn.path_info])
if path == current_path do
"active"
else
nil
end
end
Затем мы используем его как:
<%= link "Users", to: user_path(@conn, :index), class: active_class(@conn, user_path(@conn, :index))%>
Заметим, что мы user_path/2
дважды выше. Мы могли бы сушить это с помощью другого помощника:
def active_link(conn, path, opts) do
class = [opts[:class], active_class(conn, path)]
|> Enum.filter(& &1)
|> Enum.join(" ")
opts = opts
|> Keyword.put(:class, class)
|> Keyword.put(:to, path)
link text, opts
end
Зачем использовать conn.path_info
вместо conn.request_path
? Это связано с тем, что conn.request_path
вернет точный путь, который запросил пользователь. Если пользователь посещает путь /foo/
, то conn.request_path
вернет /foo/
. Проблема с этим - помощник маршрутизатора, который мы будем сравнивать, всегда будет возвращать путь /foo
без конечного /
.
Надеюсь, что это поможет! Дайте мне знать, если что-то неясно.
Ответ 2
Я создал для этого помощника, который выглядит так:
defmodule LinkHelper
@doc """
Calls `active_link/3` with a class of "active"
"""
def active_link(conn, controllers) do
active_link(conn, controllers, "active")
end
@doc """
Returns the string in the 3rd argument if the expected controller
matches the Phoenix controller that is extracted from conn. If no 3rd
argument is passed in then it defaults to "active".
The 2nd argument can also be an array of controllers that should
return the active class.
"""
def active_link(conn, controllers, class) when is_list(controllers) do
if Enum.member?(controllers, Phoenix.Controller.controller_module(conn)) do
class
else
""
end
end
def active_link(conn, controller, class) do
active_link(conn, [controller], class)
end
end
Затем я импортирую это в функцию def view
внутри web/web.ex
def view do
...
import LinkHelper
...
end
Использование:
<li class="<%= active_link(@conn, PageController)%>"><a href="<%= page_path(@conn, :index) %>">Home</a></li>
<li class="<%= active_link(@conn, [FooController, BarController])%>"><a href="<%= foo_path(@conn, :index) %>">Foo or Bar</a></li>