Programming

Rails 3에서 네비게이션에 "현재"클래스를 추가하는 가장 좋은 방법

procodes 2020. 7. 29. 20:36
반응형

Rails 3에서 네비게이션에 "현재"클래스를 추가하는 가장 좋은 방법


탐색 메뉴에 정적 페이지가 있습니다. 현재 표시된 항목에 "current"와 같은 클래스를 추가하고 싶습니다.

내가하고있는 방법은 컨트롤러와 작업을 확인하기 위해 많은 도우미 메서드 (각 항목마다 하나씩)를 추가하는 것입니다.

def current_root_class
  'class="current"' if controller_name == "homepage" && action_name == "index" 
end

<ul>
  <li <%= current_root_class %>><%= link_to "Home", root_path %>

더 좋은 방법이 있습니까?! 내 현재 방법은 너무 바보입니다 ...


나는 당신과 같은 방식으로 사용하고 있기 때문에 진정한 대답은 아닙니다. 여러 컨트롤러 또는 작업을 테스트하기 위해 도우미 메서드를 정의했습니다.

application_helper.rb에서

  def controller?(*controller)
    controller.include?(params[:controller])
  end

  def action?(*action)
    action.include?(params[:action])
  end

그런 다음 if controller?("homepage") && action?("index", "show")뷰 또는 다른 도우미 메서드에서 사용할 수 있습니다 .


나는 다음과 같은 도우미를 만들었습니다 nav_link.

def nav_link(link_text, link_path)
  class_name = current_page?(link_path) ? 'current' : ''

  content_tag(:li, :class => class_name) do
    link_to link_text, link_path
  end
end

다음과 같이 사용됩니다.

nav_link 'Home', root_path

HTML과 같은

<li class="current"><a href="/">Home</a></li>

current_page?도우미를 사용하여 "current"클래스를 할당해야하는지 여부를 결정 하십시오 . 예를 들면 다음과 같습니다.

<%= 'active' if current_page?(home_about_path) %>

다음과 같이 경로를 전달할 수도 있습니다 (옵션 해시뿐만 아니라) current_page?(root_path).


application_helper.rb (Rails 3) 에서이 nav_link (text, link) 함수를 사용하여 작업을 완료하고 부트 스트랩 트위터 2.0 탐색 막대 링크를 롤링합니다.

def nav_link(text, link)
    recognized = Rails.application.routes.recognize_path(link)
    if recognized[:controller] == params[:controller] && recognized[:action] == params[:action]
        content_tag(:li, :class => "active") do
            link_to( text, link)
        end
    else
        content_tag(:li) do
            link_to( text, link)
        end
    end
end

예:

<%=nav_link("About Us", about_path) %>

내가 한 방법은 application_helper에 도우미 함수를 추가하는 것입니다.

def current_class?(test_path)
  return 'current' if request.request_uri == test_path
  ''
end

그런 다음 탐색에서

<%= link_to 'Home', root_path, :class => current_class?(root_path) %>

현재 페이지 URI에 대한 링크 경로를 테스트하고 현재 클래스 또는 빈 문자열을 반환합니다.

나는 이것을 철저히 테스트하지 않았으며 RoR (PHP로 10 년 후 이동)에 매우 익숙하지 않으므로 큰 결함이 있으면 듣고 싶습니다.

적어도 이런 식으로 당신은 하나의 도우미 기능과 각 링크에서 간단한 호출 만 필요합니다.


@Skilldrick의 답변을 작성하려면 ...

이 코드를 application.js에 추가하면 활성화 된 자식이있는 드롭 다운 메뉴도 활성화 된 것으로 표시됩니다.

$('.active').closest('li.dropdown').addClass('active');

지원 코드를 다시 작성하려면> nav_link라는 도우미를 추가하십시오.

def nav_link_to(link_text, link_path)
  class_name = current_page?(link_path) ? 'active' : ''

  content_tag(:li, :class => class_name) do
    link_to link_text, link_path
  end
end

다음과 같이 사용됩니다.

nav_link_to 'Home', root_path

HTML과 같은

<li class="active"><a href="/">Home</a></li>

가장 좋은 방법은

application_helper.rb :

def is_active(controller, action)       
  params[:action] == action && params[:controller] == controller ? "active" : nil        
end

그리고 메뉴에서 :

<li class="<%= is_active('controller', 'action') %>">

나는 그것이 오래된 날짜의 대답이라는 것을 알고 있지만, active_link_to gem 이라는 link_to 도우미 래퍼를 사용하여 이러한 모든 현재 페이지 확인을 쉽게 무시할 수 있습니다. 현재 페이지 링크에 활성 클래스를 추가하십시오.


레일스 뷰에서 부트 스트랩 메뉴 페이지에 활성 클래스를 추가하는 방법에 대한 전체 예는 다음과 같습니다.

    <li class="<%= 'active' if current_page?(root_path) %>"><%= link_to 'Home', controller: "welcome" %></li>
    <li class="<%= 'active' if current_page?(about_path) %>"><%= link_to 'About us', about_path %></li>
   <li class="<%= 'active' if current_page?(contact_path) %>"><%= link_to 'Contact us', contact_path %></li>

Tabs on Rails 라는 멋진 보석을 사용합니다 .


개인적으로 나는 여기에 여러 대답을 사용했습니다.

<li class="<%= 'active' if current_page?(inventory_index_path) %>"><a href="#">Menu</a></li>

나는 materialize CSS를 사용하고 있으며 주요 카테고리를 접을 수있는 방법은 아래 코드를 사용하는 것입니다.

$('.active').closest(".collapsible.collapsible-accordion")
            .find(".collapsible-header")
            .click();

그것이 누군가를 돕기를 바랍니다


current_page?방법은 유연성이 충분하지 않습니다 (컨트롤러를 설정했지만 동작은하지 않고 컨트롤러의 색인 동작에서만 true를 반환합니다). 그래서 다른 답변을 기반으로했습니다.

  def nav_link_to(link_text, link_path, checks=nil)
    active = false
    if not checks.nil?
      active = true
      checks.each do |check,v|
        if not v.include? params[check]
          active = false
          break
        end
      end
    end

    return content_tag :li, :class => (active ? 'active' : '') do
      link_to link_text, link_path
    end
  end

예:

nav_link_to "Pages", pages_url, :controller => 'pages'

link_to와 똑같이 작동하지만 래핑 li 태그를 출력하도록 사용자 정의 된 nav_link의 간결한 버전이 있습니다.

application_helper.rb에 다음을 입력하십시오.

def nav_link(*args, &block)
    if block_given?
      options      = args.first || {}
      html_options = args.second
      nav_link(capture(&block), options, html_options)
    else
      name         = args[0]
      options      = args[1] || {}
      html_options = args[2]

      html_options = convert_options_to_data_attributes(options, html_options)
      url = url_for(options)

      class_name = current_page?(url) ? 'active' : nil

      href = html_options['href']
      tag_options = tag_options(html_options)

      href_attr = "href=\"#{ERB::Util.html_escape(url)}\"" unless href
      "<li class=\"#{class_name}\"><a #{href_attr}#{tag_options}>#{ERB::Util.html_escape(name || url)}</a></li>".html_safe
    end
  end

위의 코드를보고 url_helper.rb의 link_to 코드와 비교하면 유일한 차이점은 URL이 현재 페이지인지 확인하고 래핑 li 태그에 "active"클래스를 추가한다는 것입니다. 링크를 li 태그 안에 감싸고 바깥 쪽 li에 적용되는 "active"클래스를 선호하는 Twitter Bootstrap의 nav 구성 요소 와 함께 nav_link 도우미를 사용하고 있기 때문 입니다.

위의 코드에 대한 좋은 점은 link_to와 마찬가지로 블록을 함수에 전달할 수 있다는 것입니다.

예를 들어, 아이콘이있는 부트 스트랩 탐색 목록은 다음과 같습니다.

날씬한:

ul.nav.nav-list
  =nav_link root_path do
    i.icon-home
    |  Home
  =nav_link "#" do
    i.icon-user
    |  Users

산출:

<ul class="nav nav-list">
  <li class="active">
    <a href="/">
      <i class="icon-home"/>
      Home
    </a>
  </li>
  <li>
    <a href="#">
      <i class="icon-users"/>
      Users
    </a>
  </li>
</ul>

또한 link_to 도우미와 마찬가지로 HTML 옵션을 nav_link에 전달하면 태그에 적용됩니다.

앵커의 제목을 전달하는 예 :

날씬한:

ul.nav.nav-list
  =nav_link root_path, title:"Home" do
    i.icon-home
    |  Home
  =nav_link "#", title:"Users" do
    i.icon-user
    |  Users

산출:

<ul class="nav nav-list">
  <li class="active">
    <a href="/" title="Home">
      <i class="icon-home"/>
      Home
    </a>
  </li>
  <li>
    <a href="#" title="Users">
      <i class="icon-users"/>
      Users
    </a>
  </li>
</ul>

네! 이 기사를 확인하십시오 : Rails의 링크에 '선택된'클래스를 추가하는 더 좋은 방법

nav_link_helper.rb를 app / helpers에 드롭하면 다음과 같이 쉽습니다.

<%= nav_link 'My_Page', 'http://example.com/page' %>

nav_link 도우미는 표준 Rails link_to 도우미와 동일하게 작동하지만 특정 기준이 충족되면 링크 또는 래퍼에 '선택된'클래스를 추가합니다. 기본적으로 링크의 도착 URL이 현재 페이지의 URL과 동일한 URL 인 경우 기본 클래스 '선택됨'이 링크에 추가됩니다.

여기 요점이 있습니다 : https://gist.github.com/3279194

업데이트 : 이것은 이제 보석입니다 : http://rubygems.org/gems/nav_link_to


최상위 링크에 이와 같은 간단한 도우미를 사용하므로 /stories/my-story페이지에 /stories링크가 강조 표시 됩니다

def nav_link text, url

  active = (url == request.fullpath || (url != '/' && request.fullpath[0..(url.size-1)] == url))

  "<li#{ active ? " class='selected'" : '' }><a href='#{url}'>#{text}</a></li>".html_safe

end

내 솔루션을 보여 드리겠습니다.

_header.html.erb :

  <ul class="nav">
    <%= nav_tabs(@tabs) %> 
  </ul>

application_helper.rb :

 def nav_tabs(tabs=[])
    html = []
    tabs.each do |tab| 
      html << (content_tag :li, :class => ("current-page" if request.fullpath.split(/[\??]/)[0] == tab[:path]) do
        link_to tab[:path] do
          content_tag(:i, '', :class => tab[:icon]) +
          tag(:br) +
          "#{tab[:name]}"
        end
      end)        
    end

    html.join.html_safe
  end

application_controller.rb :

before_filter :set_navigation_tabs

private
def set_navigation_tabs
  @tabs = 
    if current_user && manager?
      [
        { :name => "Home", :icon => "icon-home", :path => home_index_path },
        { :name => "Portfolio", :icon => "icon-camera", :path => portfolio_home_index_path },
        { :name => "Contact", :icon => "icon-envelope-alt", :path => contact_home_index_path }
      ]
    elsif current_user && client?
      ...
    end

Skilldrick답변에 따르면 다음과 같이 변경합니다.

def nav_link(*args, &block)
  is_active = current_page?(args[0]) || current_page?(args[1])
  class_name = is_active ? 'active' : nil

  content_tag(:li, class: class_name) do
    link_to *args, &block
  end
end

훨씬 더 유용합니다.


이 버전은 @Skilldrick의 버전을 기반으로하지만 HTML 콘텐츠를 추가 할 수 있습니다.

따라서 다음을 수행 할 수 있습니다.

nav_link "A Page", a_page_path

또한 :

nav_link a_page_path do
  <strong>A Page</strong>
end

또는 다른 html 컨텐츠 (예를 들어 아이콘을 추가 할 수 있음).

도우미는 다음과 같습니다.

  def nav_link(name = nil, options = nil, html_options = nil, &block)
    html_options, options, name = options, name, block if block_given?
    options ||= {}

    html_options = convert_options_to_data_attributes(options, html_options)

    url = url_for(options)
    html_options['href'] ||= url

    class_name = current_page?(url) ? 'current' : ''
    content_tag(:li, :class => class_name) do  
      content_tag(:a, name || url, html_options, &block)
    end
  end

많은 사용 사례에 도움이 될 수있는 간단한 솔루션을 생각해 냈습니다. 이것은 나를 가능하게합니다 :

  • 일반 텍스트뿐만 아니라 HTML도 지원합니다 link_to(예 : 링크 안에 아이콘 추가)
  • 몇 줄의 코드 만 추가 application_helper.rb
  • active링크 요소가 유일한 클래스가 아닌 링크 요소의 전체 클래스 이름에 추가 하십시오.

따라서 이것을 다음에 추가하십시오 application_helper.rb.

def active_class?(class_name = nil, path)
  class_name ||= ""
  class_name += " active" if current_page?(path)
  class_name.strip!
  return class_name
end

그리고 템플릿에서 다음과 같은 것을 가질 수 있습니다.

<div class="col-xs-3">
  <%= link_to root_path, :class => active_class?("btn btn-outline-primary", root_path) do %>
    <i class="fa fa-list-alt fa-fw"></i>
  <% end %>
</div>

As bonus you can specify or not a class_name and use it like this: <div class="<%= current_page?(root_path) %>">

Thanks to previous answers 1, 2 and resources.


all these work with simple nav bars, but what about drop down sub-menu ? when a sub-menu is selected the top menu item should be made 'current' in this case tabs_on_rails me be the solution


This is how I solved in my current project.

def class_if_current_page(current_page = {}, *my_class)
    if current_page?(current_page)
      my_class.each do |klass|
        "#{klass} "
      end
    end
  end

Then..

li = link_to company_path 
    class: %w{ class_if_current_page( { status: "pending" }, "active" ), "company" } do  
      Current Company

My easy way -

application.html.erb,

<div class="navbar">
    <div class="<%= @menu1_current %> first-item"><a href="/menu1"> MENU1 </a></div>
    <div class="<%= @menu2_current %>"><a href="/menu2"> MENU2 </a></div>
    <div class="<%= @menu3_current %>"><a href="/menu3"> MENU3 </a></div>
    <div class="<%= @menu4_current %> last-item"><a href="/menu4"> MENU4 </a></div>
</div>

main_controller.erb,

class MainController < ApplicationController
    def menu1
        @menu1_current = "current"
    end

    def menu2
        @menu2_current = "current"
    end

    def menu3
        @menu3_current = "current"
    end

    def menu4
        @menu4_current = "current"
    end
end

Thanks.


If also you want to support html options hash in the view. For example if you want to call it with other CSS class or id, you can define the helper function like this.

def nav_link_to(text, url, options = {})
  options[:class] ||= ""
  options[:class] += " active"
  options[:class].strip!
  link_to text, url, options
end

So in the view, call this helper the same way you'd call link_to helper

<%= nav_link_to "About", about_path, class: "my-css-class" %>

Create a method in ApplicationHelper as below.

def active controllers, action_names = nil
  class_name = controllers.split(",").any? { |c| controller.controller_name == c.strip } ? "active" : ""
  if class_name.present? && action_names.present?
    return action_names.split(",").any? { |an| controller.action_name == an.strip } ? "active" : ""
  end
  class_name
end

Now use it in view as below use cases.

1. 특정 컨트롤러의 모든 동작

<li class="<%= active('controller_name')%>">
....
</li>

2. 많은 컨트롤러의 모든 동작 (쉼표가 분리 된 상태)

<li class="<%= active('controller_name1,controller_name2')%>">
....
</li>

3. 특정 컨트롤러의 특정 작업

<li class="<%= active('controller_name', 'action_name')%>">
....
</li>

4. 많은 컨트롤러의 특정 동작 (쉼표로 구분)

<li class="<%= active('controller_name1,controller_name2', 'action_name')%>">
....
</li>

5. 특정 컨트롤러의 특정 작업

<li class="<%= active('controller_name', 'index, show')%>">
....
</li>

6. 많은 컨트롤러의 일부 특정 동작 (쉼표가 분리 된 상태)

<li class="<%= active('controller_name1,controller_name2', 'index, show')%>">
....
</li>

그것이 도움이되기를 바랍니다.

참고 URL : https://stackoverflow.com/questions/3705898/best-way-to-add-current-class-to-nav-in-rails-3

반응형