Commit f064c84019f7414cb9cfa9e49fb735dba7f495df

Authored by Robert Speicher
1 parent aa0c4b77

Add nav_link helper to TabHelper

app/helpers/tab_helper.rb
1 1 module TabHelper
  2 + # Navigation link helper
  3 + #
  4 + # Returns an `li` element with an 'active' class if the supplied
  5 + # controller(s) and/or action(s) currently active. The contents of the
  6 + # element is the value passed to the block.
  7 + #
  8 + # options - The options hash used to determine if the element is "active" (default: {})
  9 + # :controller - One or more controller names to check (optional).
  10 + # :action - One or more action names to check (optional).
  11 + # :path - A shorthand path, such as 'dashboard#index', to check (optional).
  12 + # :html_options - Extra options to be passed to the list element (optional).
  13 + # block - An optional block that will become the contents of the returned
  14 + # `li` element.
  15 + #
  16 + # When both :controller and :action are specified, BOTH must match in order
  17 + # to be marked as active. When only one is given, either can match.
  18 + #
  19 + # Examples
  20 + #
  21 + # # Assuming we're on TreeController#show
  22 + #
  23 + # # Controller matches, but action doesn't
  24 + # nav_link(controller: [:tree, :refs], action: :edit) { "Hello" }
  25 + # # => '<li>Hello</li>'
  26 + #
  27 + # # Controller matches
  28 + # nav_link(controller: [:tree, :refs]) { "Hello" }
  29 + # # => '<li class="active">Hello</li>'
  30 + #
  31 + # # Shorthand path
  32 + # nav_link(path: 'tree#show') { "Hello" }
  33 + # # => '<li class="active">Hello</li>'
  34 + #
  35 + # # Supplying custom options for the list element
  36 + # nav_link(controller: :tree, html_options: {class: 'home'}) { "Hello" }
  37 + # # => '<li class="home active">Hello</li>'
  38 + #
  39 + # Returns a list item element String
  40 + def nav_link(options = {}, &block)
  41 + if path = options.delete(:path)
  42 + c, a, _ = path.split('#')
  43 + else
  44 + c = options.delete(:controller)
  45 + a = options.delete(:action)
  46 + end
  47 +
  48 + if c && a
  49 + # When given both options, make sure BOTH are active
  50 + klass = current_controller?(*c) && current_action?(*a) ? 'active' : ''
  51 + else
  52 + # Otherwise check EITHER option
  53 + klass = current_controller?(*c) || current_action?(*a) ? 'active' : ''
  54 + end
  55 +
  56 + # Add our custom class into the html_options, which may or may not exist
  57 + # and which may or may not already have a :class key
  58 + o = options.delete(:html_options) || {}
  59 + o[:class] ||= ''
  60 + o[:class] += ' ' + klass
  61 + o[:class].strip!
  62 +
  63 + if block_given?
  64 + content_tag(:li, capture(&block), o)
  65 + else
  66 + content_tag(:li, nil, o)
  67 + end
  68 + end
  69 +
2 70 def tab_class(tab_key)
3 71 active = case tab_key
4 72  
... ...
spec/helpers/tab_helper_spec.rb 0 → 100644
... ... @@ -0,0 +1,44 @@
  1 +require 'spec_helper'
  2 +
  3 +describe TabHelper do
  4 + include ApplicationHelper
  5 +
  6 + describe 'nav_link' do
  7 + before do
  8 + controller.stub!(:controller_name).and_return('foo')
  9 + stub!(:action_name).and_return('foo')
  10 + end
  11 +
  12 + it "captures block output" do
  13 + nav_link { "Testing Blocks" }.should match(/Testing Blocks/)
  14 + end
  15 +
  16 + it "performs checks on the current controller" do
  17 + nav_link(controller: :foo).should match(/<li class="active">/)
  18 + nav_link(controller: :bar).should_not match(/active/)
  19 + nav_link(controller: [:foo, :bar]).should match(/active/)
  20 + end
  21 +
  22 + it "performs checks on the current action" do
  23 + nav_link(action: :foo).should match(/<li class="active">/)
  24 + nav_link(action: :bar).should_not match(/active/)
  25 + nav_link(action: [:foo, :bar]).should match(/active/)
  26 + end
  27 +
  28 + it "performs checks on both controller and action when both are present" do
  29 + nav_link(controller: :bar, action: :foo).should_not match(/active/)
  30 + nav_link(controller: :foo, action: :bar).should_not match(/active/)
  31 + nav_link(controller: :foo, action: :foo).should match(/active/)
  32 + end
  33 +
  34 + it "accepts a path shorthand" do
  35 + nav_link(path: 'foo#bar').should_not match(/active/)
  36 + nav_link(path: 'foo#foo').should match(/active/)
  37 + end
  38 +
  39 + it "passes extra html options to the list element" do
  40 + nav_link(action: :foo, html_options: {class: 'home'}).should match(/<li class="home active">/)
  41 + nav_link(html_options: {class: 'active'}).should match(/<li class="active">/)
  42 + end
  43 + end
  44 +end
... ...