रेल में "वर्तमान" वर्ग को जोड़ने के लिए सबसे अच्छा तरीका रेल 3


111

नेविगेशन मेनू में मेरे कुछ स्थिर पृष्ठ हैं। मैं उस आइटम में "वर्तमान" जैसी श्रेणी जोड़ना चाहता हूं जो वर्तमान में प्रदर्शित हो रही है।

जिस तरह से मैं कर रहा हूं वह नियंत्रक और कार्रवाई की जांच करने के लिए सहायक विधियों (प्रत्येक एक आइटम के लिए) के टन को जोड़ने के लिए है।

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

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

क्या ऐसा करने का कोई बेहतर तरीका है !? मेरा वर्तमान तरीका बहुत बेवकूफ है ......

जवाबों:


56

यहाँ वास्तव में एक उत्तर नहीं है, क्योंकि मैं उसी तरह का उपयोग कर रहा हूं जैसे आप कर रहे हैं। मैंने कई नियंत्रक या क्रियाओं के परीक्षण के लिए सिर्फ सहायक विधियों को परिभाषित किया है:

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")अपने विचार या अन्य सहायक विधियों का उपयोग कर सकते हैं ...


आपका तरीका सबसे अच्छा है जब अलग-अलग नियंत्रक / कार्यों द्वारा नियंत्रित किए गए कुछ पृष्ठ हैं लेकिन एक ही मेनू आइटम में, सही? क्या आपको अधिक लाभ का सामना करना पड़ा ~?
पीटरवॉन्ग

वाक्य रचना की संक्षिप्तता के अलावा और कोई लाभ नहीं। मैं यह देखने के लिए उत्सुक हूं कि क्या किसी और के पास बेहतर समाधान है।
यानिस

मैंने इस विधि को बड़ी सफलता के साथ किया। इस कोड को दृश्य में जोड़ा गया: <% = link_to "उपयोगकर्ता", users_path, वर्ग: (नियंत्रक? ("उपयोगकर्ता")? 'चयनित': nil)%> वास्तव में साफ है कि यह दोनों / उपयोगकर्ताओं और / उपयोगकर्ताओं / नए के लिए काम करता है? ।
एंड्रियास

1
एक सुधार शायद हो सकता है controller_nameऔर action_nameइसके बजाय शायद परमेश्‍वर
फ्रांसेस्को बेलाडोना

बहुत बढ़िया। मैंने इस सरल को रखने के बारे में नहीं सोचा था लेकिन यह बहुत अच्छी तरह से तराजू। +1
न्यूडार्क-इट

290

मैंने एक सहायक को बुलाया 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>

3
यदि आप ट्विटर बूटस्ट्रैप navbar twitter twitter.github.com/bootstrap/examples/hero.html पर
Mc में

41
Class_name = current_page में बदलें? (Link_path)? 'current': nil यदि आप नहीं चाहते कि क्लास टैग तब न दिखे जब वह वर्तमान पृष्ठ पर न हो
मैथ्यू हुई

1
आप ड्रॉपडाउन में उपयोग की गई नेस्टेड सूचियों के लिए इसे कैसे संशोधित करेंगे?
doremi

9
एक रेगिस्तान के रूप में DRY
ऑरलैंडो

1
मैंने कुछ अतिरिक्त तर्क जोड़े हैं extra_classes = nil, id = nil फिर content_tag content_tag (: li, class: [class_name, extra_classes], id: id) के अंदर ताकि आप अपनी कक्षाओं और आईडी के तत्वों को भी जोड़ सकें। :)
जॉन

72

current_page?यह निर्धारित करने के लिए सहायक का उपयोग करें कि आपको "current"कक्षा आवंटित करनी चाहिए या नहीं । उदाहरण के लिए:

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

ध्यान दें कि आप एक रास्ता भी पास कर सकते हैं (न केवल विकल्पों का एक हैश), जैसे current_page?(root_path):।


3
क्या क्वेरी परमेस को अनदेखा करने के लिए इसे प्राप्त करने का कोई तरीका है?
मोहम्मद

@ मोहम्मद, आप ऐसा कर सकते हैं: current_page? (नियंत्रक: 'उपयोगकर्ता', कार्रवाई: 'सूचकांक')
nilid

26

मैं इस काम को करने के लिए application_helper.rb (रेल्स 3) में इस nav_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) %>

इस current_page?पद्धति का उपयोग करके इसे सरल बनाया जा सकता है , जैसा कि अन्य उत्तरों में है।
तेमू लीस्टी

10

जिस तरह से मैंने किया है वह 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 के साथ एक दशक से अधिक समय के बाद आगे बढ़ना) के लिए बहुत नया हूं, अगर यह एक बड़ी खामी है तो मुझे इसे सुनना अच्छा लगेगा।

कम से कम इस तरह से आपको केवल 1 सहायक फ़ंक्शन और प्रत्येक लिंक में एक साधारण कॉल की आवश्यकता है।


1
बस एक समस्या है। मैंने request_uri के बजाय request.path का उपयोग किया (request_uri काम नहीं कर रहा था, शायद संस्करण की समस्या?)। आपका जवाब मेरी राय में साफ और सुरुचिपूर्ण है।
टोनी

6

@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>

4

मुझे लगता है कि सबसे अच्छा तरीका है

application_helper.rb:

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

और मेनू में:

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

क्या इस तरह एक खाली वर्ग "" को छोड़ना ठीक है?
हर्ष एमवी

हाँ। यह अजीब लग सकता है यदि आप स्रोत को खाली वर्ग विशेषताओं का एक गुच्छा देखते हैं, लेकिन यह वैध HTML है।
कोबाल्ट्ज

आप उपयोग कर सकते हैं <%= content_tag(:li, "Click me", class: is_active('controller', 'action')) %>, यह शून्य के लिए एक वर्ग विशेषता मुद्रित नहीं करेगा। apidock.com/rails/ActionView/Helpers/TagHelper/content_tag
neonmate

4

मुझे पता है कि यह एक आउट डेटेड उत्तर है, लेकिन आप इन सभी वर्तमान पेज की जांच को आसानी से अनदेखा कर सकते हैं एक link_to हेल्पर आवरण का उपयोग करके, जिसे active_link_to रत्न कहा जाता है , यह ठीक उसी तरह काम करता है जैसा आप चाहते हैं, वर्तमान पृष्ठ लिंक में एक सक्रिय वर्ग जोड़ें


4

यहां पूर्ण उदाहरण है, रेल दृश्य में बूटस्ट्रैप मेनू पृष्ठ पर एक सक्रिय वर्ग कैसे जोड़ें।

    <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>

3

मैं एक भयानक मणि का उपयोग करता हूं जिसे टैब्स ऑन रेल्स कहा जाता है ।


1
सलाह के लिये धन्यवाद। चूंकि मेरी नौसेना इतनी सरल है और छोटी वस्तुओं के साथ केवल एक ही है, मणि शायद अति-संचालित होगी।
पीटरवॉन्ग

3

मेरे पास nav_link का अधिक रसीला संस्करण है जो बिल्कुल link_to की तरह काम करता है, लेकिन रैपिंग ली टैग को आउटपुट करने के लिए अनुकूलित है।

निम्नलिखित को अपने 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 वर्तमान पृष्ठ है, और वर्ग "सक्रिय" को रैपिंग ली टैग में जोड़ता है। इसका कारण यह है कि मैं के साथ ट्विटर बूटस्ट्रैप के 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>

बहुत बढ़िया। मेरे लिए यह सबसे व्यवहार्य विकल्प था क्योंकि यह ब्लॉक की अनुमति देता है। अनेक अनेक धन्यवाद!
कास्परि

3

मेरे लिए व्यक्तिगत रूप से मैंने यहां उत्तरों के संयोजन का उपयोग किया

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

मैं भौतिकीकृत सीएसएस का उपयोग कर रहा हूं और मुख्य श्रेणियों को संक्षिप्त बनाने का मेरा तरीका नीचे दिए गए कोड का उपयोग करके है

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

आशा है कि यह किसी की मदद करता है


इस बारे में भूल गया। इसे एक अनुस्मारक के रूप में पोस्ट करने के लिए धन्यवाद।
newdark-it

2

current_page?विधि तो मैं अन्य उत्तरों के आधार पर यह कर दिया है, मेरे लिए लचीला पर्याप्त (यदि आप किसी नियंत्रक नहीं बल्कि एक कार्रवाई सेट तो यह केवल नियंत्रक के सूचकांक कार्रवाई पर सही वापस आ जाएंगे, कहते हैं) नहीं है:

  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'

आपके उत्तर के लिए धन्यवाद। मुझे लगता है कि आपका वास्तव में स्वीकृत उत्तर के समान है :)
पीटरवॉन्ग

Google के माध्यम से मुझे यह उत्तर आया, क्योंकि मुझे यह समस्या हो रही थी, इसलिए मैंने सोचा कि मैं हर किसी की मदद करूँगा जो इस पार भी आता है :)
unrelativity

2

हां! इस लेख को देखें: रेल में लिंक के लिए 'चयनित' वर्ग जोड़ने का एक बेहतर तरीका

ऐप्लिकेशन / सहायकों में nav_link_helper.rb छोड़ें और यह जितना आसान हो सकता है:

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

Nav_link सहायक मानक रेल की तरह ही काम करता है link_to सहायक, लेकिन कुछ मानदंडों को पूरा करने पर आपके लिंक (या इसके आवरण) में एक 'चयनित' वर्ग जोड़ता है। डिफ़ॉल्ट रूप से, यदि लिंक का गंतव्य यूआरएल वर्तमान पृष्ठ के यूआरएल के समान यूआरएल है, तो लिंक में 'चयनित' का एक डिफ़ॉल्ट वर्ग जोड़ा जाता है।

यहाँ एक जिस्ट है: https://gist.github.com/3279194

अद्यतन: यह अब एक मणि है: http://rubygems.org/gems/nav_link_to


यह अच्छा है। मैंने उपयोग में लिया, और अचयनित तत्वों को एक वर्ग का नाम देने के लिए एक संशोधन जोड़ा, साथ ही, यह भी बताया कि टिप्पणी में।
तेमू लीस्टी

2

मैं इस तरह के शीर्ष स्तर के लिंक के लिए एक साधारण सहायक का उपयोग करता हूं इसलिए /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

2

मुझे अपना समाधान दिखाने दें:

_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

1

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

इसे और अधिक उपयोगी बनाने के लिए।


1

यह संस्करण @ 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

1

मुझे लगता है कि मैं एक सरल समाधान के साथ आया हूं जो बहुत सारे उपयोग के मामलों के लिए सहायक हो सकता है। यह मुझे देता है:

  • न केवल सादे पाठ बल्कि 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>

बोनस के रूप में आप इसे निर्दिष्ट या class_nameउपयोग नहीं कर सकते हैं और इसे इस तरह से उपयोग कर सकते हैं :<div class="<%= current_page?(root_path) %>">

पिछले उत्तर 1 , 2 और संसाधनों के लिए धन्यवाद ।


0

इन सभी सरल नौसेना सलाखों के साथ काम करते हैं, लेकिन उप-मेनू को नीचे लाने के बारे में क्या? जब एक उप-मेनू का चयन किया जाता है तो शीर्ष मेनू आइटम को इस मामले में 'चालू' बनाया जाना चाहिए tabs_on_rails मुझे समाधान होना चाहिए


0

यह मैंने अपनी वर्तमान परियोजना में हल किया है।

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

फिर..

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

0

मेरा आसान तरीका -

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

धन्यवाद।


0

अगर आप भी देखने में html विकल्प हैश का समर्थन करना चाहते हैं। उदाहरण के लिए यदि आप इसे अन्य सीएसएस वर्ग या आईडी के साथ कॉल करना चाहते हैं, तो आप सहायक फ़ंक्शन को इस तरह परिभाषित कर सकते हैं।

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

इसलिए देखने में, इस सहायक को उसी तरह से कॉल करें जिस तरह से आप link_to सहायक को कॉल करेंगे

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

0

ApplicationHelperनीचे के रूप में एक विधि बनाएँ ।

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

अब इसे नीचे उपयोग मामलों के रूप में देखने में उपयोग करें।

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>

आशा करता हूँ की ये काम करेगा

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.