simple-navigation 3.12.0 → 3.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. data/CHANGELOG +4 -0
  2. data/generators/navigation_config/navigation_config_generator.rb +3 -3
  3. data/generators/navigation_config/templates/config/navigation.rb +9 -10
  4. data/init.rb +1 -1
  5. data/lib/generators/navigation_config/navigation_config_generator.rb +11 -6
  6. data/lib/simple-navigation.rb +1 -1
  7. data/lib/simple_navigation.rb +93 -65
  8. data/lib/simple_navigation/adapters/base.rb +16 -16
  9. data/lib/simple_navigation/adapters/nanoc.rb +7 -6
  10. data/lib/simple_navigation/adapters/padrino.rb +5 -7
  11. data/lib/simple_navigation/adapters/rails.rb +52 -39
  12. data/lib/simple_navigation/adapters/sinatra.rb +14 -17
  13. data/lib/simple_navigation/core/configuration.rb +73 -34
  14. data/lib/simple_navigation/core/item.rb +110 -54
  15. data/lib/simple_navigation/core/item_adapter.rb +18 -13
  16. data/lib/simple_navigation/core/item_container.rb +93 -66
  17. data/lib/simple_navigation/core/items_provider.rb +12 -10
  18. data/lib/simple_navigation/rails_controller_methods.rb +98 -78
  19. data/lib/simple_navigation/rendering/helpers.rb +130 -68
  20. data/lib/simple_navigation/rendering/renderer/base.rb +30 -25
  21. data/lib/simple_navigation/rendering/renderer/breadcrumbs.rb +26 -19
  22. data/lib/simple_navigation/rendering/renderer/json.rb +11 -13
  23. data/lib/simple_navigation/rendering/renderer/links.rb +18 -13
  24. data/lib/simple_navigation/rendering/renderer/list.rb +28 -15
  25. data/lib/simple_navigation/rendering/renderer/text.rb +7 -12
  26. data/lib/simple_navigation/version.rb +1 -1
  27. data/spec/lib/simple_navigation/core/item_adapter_spec.rb +1 -1
  28. data/spec/lib/simple_navigation/core/item_container_spec.rb +118 -68
  29. data/spec/lib/simple_navigation_spec.rb +16 -5
  30. metadata +2 -2
@@ -1,9 +1,10 @@
1
1
  require 'forwardable'
2
2
 
3
3
  module SimpleNavigation
4
-
5
- # This class acts as an adapter to items that are not defined using the DSL in the config/navigation.rb, but directly provided inside the application.
6
- # When defining the items that way, every item you provide needs to define the following methods:
4
+ # This class acts as an adapter to items that are not defined using the DSL
5
+ # in the config/navigation.rb, but directly provided inside the application.
6
+ # When defining the items that way, every item you provide needs to define
7
+ # the following methods:
7
8
  #
8
9
  # * <tt>key</tt>
9
10
  # * <tt>name</tt>
@@ -12,10 +13,13 @@ module SimpleNavigation
12
13
  # and optionally
13
14
  #
14
15
  # * <tt>options</tt>
15
- # * <tt>items</tt> - if one of your items has a subnavigation it must respond to <tt>items</tt> providing the subnavigation.
16
+ # * <tt>items</tt> - if one of your items has a subnavigation it must respond
17
+ # to <tt>items</tt> providing the subnavigation.
16
18
  #
17
- # You can also specify your items as a list of hashes. The hashes will be converted to objects automatically.
18
- # The hashes representing the items obviously must have the keys :key, :name and :url and optionally the keys :options and :items.
19
+ # You can also specify your items as a list of hashes.
20
+ # The hashes will be converted to objects automatically.
21
+ # The hashes representing the items obviously must have the keys :key, :name
22
+ # and :url and optionally the keys :options and :items.
19
23
  #
20
24
  # See SimpleNavigation::ItemContainer#item for the purpose of these methods.
21
25
  class ItemAdapter
@@ -29,14 +33,16 @@ module SimpleNavigation
29
33
  @item = item.is_a?(Hash) ? to_object(item) : item
30
34
  end
31
35
 
32
- # Returns the options for this item. If the wrapped item does not implement an options method, an empty hash is returned.
36
+ # Returns the options for this item. If the wrapped item does not implement
37
+ # an options method, an empty hash is returned.
33
38
  def options
34
- @item.respond_to?(:options) ? @item.options : {}
39
+ item.respond_to?(:options) ? item.options : {}
35
40
  end
36
41
 
37
- # Returns the items (subnavigation) for this item if it responds to :items and the items-collection is not empty. Returns nil otherwise.
42
+ # Returns the items (subnavigation) for this item if it responds to :items
43
+ # and the items-collection is not empty. Returns nil otherwise.
38
44
  def items
39
- (@item.respond_to?(:items) && !(@item.items.nil? || @item.items.empty?)) ? @item.items : nil
45
+ item.items if item.respond_to?(:items) && item.items && item.items.any?
40
46
  end
41
47
 
42
48
  # Converts this Item into a SimpleNavigation::Item
@@ -46,8 +52,8 @@ module SimpleNavigation
46
52
 
47
53
  protected
48
54
 
49
- # Converts the specified hash into an object. Each key will be added as method.
50
- #
55
+ # Converts the specified hash into an object. Each key will be added
56
+ # as method.
51
57
  def to_object(hash)
52
58
  mod = Module.new do
53
59
  hash.each_pair do |key, value|
@@ -58,6 +64,5 @@ module SimpleNavigation
58
64
  end
59
65
  Object.new.extend(mod)
60
66
  end
61
-
62
67
  end
63
68
  end
@@ -1,117 +1,137 @@
1
1
  module SimpleNavigation
2
-
3
2
  # Holds the Items for a navigation 'level'.
4
3
  class ItemContainer
4
+ attr_accessor :auto_highlight,
5
+ :dom_class,
6
+ :dom_id,
7
+ :renderer,
8
+ :selected_class
5
9
 
6
10
  attr_reader :items, :level
7
- attr_accessor :renderer, :dom_id, :dom_class, :dom_attributes, :auto_highlight, :selected_class
8
11
 
9
- def initialize(level=1) #:nodoc:
12
+ attr_writer :dom_attributes
13
+
14
+ def initialize(level = 1) #:nodoc:
10
15
  @level = level
11
- @items = []
16
+ @items ||= []
12
17
  @renderer = SimpleNavigation.config.renderer
13
18
  @auto_highlight = true
14
19
  end
15
20
 
16
21
  def dom_attributes
17
22
  # backward compability for #dom_id and #dom_class
18
- (@dom_attributes || {}).merge({id: dom_id, class: dom_class}.reject{|k, v| v.nil?})
23
+ dom_id_and_class = {
24
+ id: dom_id,
25
+ class: dom_class
26
+ }.reject { |_, v| v.nil? }
27
+ (@dom_attributes || {}).merge(dom_id_and_class)
19
28
  end
20
29
 
21
30
  # Creates a new navigation item.
22
31
  #
23
- # The <tt>key</tt> is a symbol which uniquely defines your navigation item in the scope of the primary_navigation or the sub_navigation.
32
+ # The <tt>key</tt> is a symbol which uniquely defines your navigation item
33
+ # in the scope of the primary_navigation or the sub_navigation.
24
34
  #
25
- # The <tt>name</tt> will be displayed in the rendered navigation. This can also be a call to your I18n-framework.
35
+ # The <tt>name</tt> will be displayed in the rendered navigation.
36
+ # This can also be a call to your I18n-framework.
26
37
  #
27
- # The <tt>url</tt> is the address that the generated item points to. You can also use url_helpers (named routes, restful routes helper, url_for etc.) <tt>url</tt> is optional - items without URLs should not be rendered as links.
38
+ # The <tt>url</tt> is the address that the generated item points to.
39
+ # You can also use url_helpers (named routes, restful routes helper,
40
+ # url_for, etc). <tt>url</tt> is optional - items without URLs should not
41
+ # be rendered as links.
28
42
  #
29
43
  # The <tt>options</tt> can be used to specify the following things:
30
- # * <tt>any html_attributes</tt> - will be included in the rendered navigation item (e.g. id, class etc.)
44
+ # * <tt>any html_attributes</tt> - will be included in the rendered
45
+ # navigation item (e.g. id, class etc.)
31
46
  # * <tt>:if</tt> - Specifies a proc to call to determine if the item should
32
- # be rendered (e.g. <tt>:if => Proc.new { current_user.admin? }</tt>). The
33
- # proc should evaluate to a true or false value and is evaluated in the context of the view.
34
- # * <tt>:unless</tt> - Specifies a proc to call to determine if the item should not
35
- # be rendered (e.g. <tt>:unless => Proc.new { current_user.admin? }</tt>). The
36
- # proc should evaluate to a true or false value and is evaluated in the context of the view.
37
- # * <tt>:method</tt> - Specifies the http-method for the generated link - default is :get.
38
- # * <tt>:highlights_on</tt> - if autohighlighting is turned off and/or you want to explicitly specify
39
- # when the item should be highlighted, you can set a regexp which is matched againstthe current URI.
47
+ # be rendered (e.g. <tt>if: Proc.new { current_user.admin? }</tt>). The
48
+ # proc should evaluate to a true or false value and is evaluated
49
+ # in the context of the view.
50
+ # * <tt>:unless</tt> - Specifies a proc to call to determine if the item
51
+ # should not be rendered
52
+ # (e.g. <tt>unless: Proc.new { current_user.admin? }</tt>).
53
+ # The proc should evaluate to a true or false value and is evaluated in
54
+ # the context of the view.
55
+ # * <tt>:method</tt> - Specifies the http-method for the generated link -
56
+ # default is :get.
57
+ # * <tt>:highlights_on</tt> - if autohighlighting is turned off and/or you
58
+ # want to explicitly specify when the item should be highlighted, you can
59
+ # set a regexp which is matched againstthe current URI.
40
60
  #
41
61
  # The <tt>block</tt> - if specified - will hold the item's sub_navigation.
42
62
  def item(key, name, url_or_options = {}, options_or_nil = {}, &block)
43
63
  options = url_or_options.is_a?(Hash) ? url_or_options : options_or_nil
44
- (@items << SimpleNavigation::Item.new(self, key, name, url_or_options, options_or_nil, nil, &block)) if should_add_item?(options)
64
+ return unless should_add_item?(options)
65
+ items << SimpleNavigation::Item.new(self,
66
+ key,
67
+ name,
68
+ url_or_options,
69
+ options_or_nil,
70
+ nil,
71
+ &block)
45
72
  end
46
73
 
47
- def items=(items)
48
- items.each do |item|
49
- item = SimpleNavigation::ItemAdapter.new(item)
50
- (@items << item.to_simple_navigation_item(self)) if should_add_item?(item.options)
51
- end
74
+ def items=(new_items)
75
+ @items += new_items.map { |item| ItemAdapter.new(item) }
76
+ .keep_if { |item| should_add_item?(item.options) }
52
77
  end
53
78
 
54
79
  # Returns the Item with the specified key, nil otherwise.
55
80
  #
56
81
  def [](navi_key)
57
- items.find {|i| i.key == navi_key}
82
+ items.find { |item| item.key == navi_key }
58
83
  end
59
84
 
60
85
  # Returns the level of the item specified by navi_key.
61
- # Recursively works its way down the item's sub_navigations if the desired item is not found directly in this container's items.
62
- # Returns nil item cannot be found.
86
+ # Recursively works its way down the item's sub_navigations if the desired
87
+ # item is not found directly in this container's items.
88
+ # Returns nil if item cannot be found.
63
89
  #
64
90
  def level_for_item(navi_key)
65
- my_item = self[navi_key]
66
- return self.level if my_item
67
- items.each do |i|
68
- if i.sub_navigation
69
- level = i.sub_navigation.level_for_item(navi_key)
70
- return level unless level.nil?
71
- end
91
+ return level if self[navi_key]
92
+
93
+ items.each do |item|
94
+ next unless item.sub_navigation
95
+ level = item.sub_navigation.level_for_item(navi_key)
96
+ return level if level
72
97
  end
73
98
  return nil
74
99
  end
75
100
 
76
101
  # Renders the items in this ItemContainer using the configured renderer.
77
102
  #
78
- # The options are the same as in the view's render_navigation call (they get passed on)
79
- def render(options={})
80
- renderer_instance = if options[:renderer]
81
- if options[:renderer].instance_of?(Symbol) && SimpleNavigation.registered_renderers.key?(options[:renderer])
82
- SimpleNavigation.registered_renderers[options[:renderer]].new(options)
83
- else
84
- options[:renderer].new(options)
85
- end
86
- else
87
- self.renderer.new(options)
88
- end
89
- renderer_instance.render(self)
103
+ # The options are the same as in the view's render_navigation call
104
+ # (they get passed on)
105
+ def render(options = {})
106
+ renderer_instance(options).render(self)
90
107
  end
91
108
 
92
109
  # Returns true if any of this container's items is selected.
93
110
  #
94
111
  def selected?
95
- items.any? {|i| i.selected?}
112
+ items.any?(&:selected?)
96
113
  end
97
114
 
98
115
  # Returns the currently selected item, nil if no item is selected.
99
116
  #
100
117
  def selected_item
101
- items.find {|i| i.selected?}
118
+ items.find(&:selected?)
102
119
  end
103
120
 
104
121
  # Returns the active item_container for the specified level
105
- # (recursively looks up items in selected sub_navigation if level is deeper than this container's level).
106
- #
122
+ # (recursively looks up items in selected sub_navigation if level is deeper
123
+ # than this container's level).
107
124
  def active_item_container_for(desired_level)
108
- return self if self.level == desired_level
109
- return nil unless selected_sub_navigation?
110
- return selected_item.sub_navigation.active_item_container_for(desired_level)
125
+ if level == desired_level
126
+ self
127
+ elsif selected_sub_navigation?
128
+ selected_item.sub_navigation.active_item_container_for(desired_level)
129
+ end
111
130
  end
112
-
113
- # Returns the deepest possible active item_container.
114
- # (recursively searches in the sub_navigation if this container has a selected sub_navigation).
131
+
132
+ # Returns the deepest possible active item_container.
133
+ # (recursively searches in the sub_navigation if this container has a
134
+ # selected sub_navigation).
115
135
  def active_leaf_container
116
136
  if selected_sub_navigation?
117
137
  selected_item.sub_navigation.active_leaf_container
@@ -127,26 +147,33 @@ module SimpleNavigation
127
147
 
128
148
  private
129
149
 
150
+ # FIXME: raise an exception if :rederer is a symbol and it is not registred
151
+ # in SimpleNavigation.registered_renderers
152
+ def renderer_instance(options)
153
+ return renderer.new(options) unless options[:renderer]
154
+
155
+ if options[:renderer].is_a?(Symbol)
156
+ registered_renderer = SimpleNavigation.registered_renderers[options[:renderer]]
157
+ registered_renderer.new(options)
158
+ else
159
+ options[:renderer].new(options)
160
+ end
161
+ end
162
+
130
163
  def selected_sub_navigation?
131
164
  !!(selected_item && selected_item.sub_navigation)
132
165
  end
133
166
 
134
- # partially borrowed from ActionSupport::Callbacks
135
- def should_add_item?(options) #:nodoc:
167
+ def should_add_item?(options)
136
168
  [options.delete(:if)].flatten.compact.all? { |m| evaluate_method(m) } &&
137
- ![options.delete(:unless)].flatten.compact.any? { |m| evaluate_method(m) }
169
+ [options.delete(:unless)].flatten.compact.none? { |m| evaluate_method(m) }
138
170
  end
139
171
 
140
- # partially borrowed from ActionSupport::Callbacks
141
- def evaluate_method(method) #:nodoc:
172
+ def evaluate_method(method)
142
173
  case method
143
- when Proc, Method
144
- method.call
145
- else
146
- raise ArgumentError, ":if or :unless must be procs or lambdas"
174
+ when Proc, Method then method.call
175
+ else fail(ArgumentError, ':if or :unless must be procs or lambdas')
147
176
  end
148
177
  end
149
-
150
178
  end
151
-
152
179
  end
@@ -1,18 +1,19 @@
1
1
  module SimpleNavigation
2
-
3
- # Acts as a proxy to navigation items that are passed into the SimpleNavigation::Configuration#items method. It hides the logic
4
- # for finding items from the Configuration object.
2
+ # Acts as a proxy to navigation items that are passed into the
3
+ # SimpleNavigation::Configuration#items method.
4
+ # It hides the logic for finding items from the Configuration object.
5
5
  #
6
6
  class ItemsProvider
7
-
8
7
  attr_reader :provider
9
8
 
10
9
  # It accepts the following types of provider:
11
- # * methodname as symbol - the specified method should return the relevant items and has to be available in the view (a helper method)
10
+ # * methodname as symbol - the specified method should return the relevant
11
+ # items and has to be available in the view (a helper method)
12
12
  # * object that responds to :items
13
13
  # * enumerable object that represents the items
14
14
  #
15
- # See SimpleNavigation::ItemAdapter for the requirements that need to be fulfilled by the provided items.
15
+ # See SimpleNavigation::ItemAdapter for the requirements that need to be
16
+ # fulfilled by the provided items.
16
17
  #
17
18
  def initialize(provider)
18
19
  @provider = provider
@@ -20,16 +21,17 @@ module SimpleNavigation
20
21
 
21
22
  # Returns the navigation items
22
23
  def items
23
- if provider.instance_of?(Symbol)
24
+ if provider.is_a?(Symbol)
24
25
  SimpleNavigation.context_for_eval.send(provider)
25
26
  elsif provider.respond_to?(:items)
26
27
  provider.items
27
28
  elsif provider.respond_to?(:each)
28
29
  provider
29
30
  else
30
- raise "items_provider either must be a symbol specifying the helper-method to call, an object with an items-method defined or an enumerable representing the items"
31
+ fail('items_provider either must be a symbol specifying the ' \
32
+ 'helper-method to call, an object with an items-method defined ' \
33
+ 'or an enumerable representing the items')
31
34
  end
32
35
  end
33
-
34
36
  end
35
- end
37
+ end
@@ -1,60 +1,73 @@
1
1
  module SimpleNavigation
2
+ def self.explicit_navigation_args
3
+ adapter.controller.instance_variable_get(:'@sn_current_navigation_args')
4
+ end
2
5
 
3
- class << self
6
+ # Reads the current navigation for the specified level from the controller.
7
+ # Returns nil if there is no current navigation set for level.
8
+ def self.current_navigation_for(level)
9
+ adapter.controller.instance_variable_get(:"@sn_current_navigation_#{level}")
10
+ end
4
11
 
5
- def explicit_navigation_args
6
- self.adapter.controller.instance_variable_get(:"@sn_current_navigation_args")
7
- end
12
+ # If any navigation has been explicitely set in the controller this method
13
+ # evaluates the specified args set in the controller and sets the correct
14
+ # instance variable in the controller.
15
+ def self.handle_explicit_navigation
16
+ return unless explicit_navigation_args
17
+ level, navigation = parse_explicit_navigation_args
18
+ navigation_level = :"@sn_current_navigation_#{level}"
19
+ adapter.controller.instance_variable_set(navigation_level, navigation)
20
+ end
8
21
 
9
- # Reads the current navigation for the specified level from the controller.
10
- # Returns nil if there is no current navigation set for level.
11
- def current_navigation_for(level)
12
- self.adapter.controller.instance_variable_get(:"@sn_current_navigation_#{level}")
13
- end
22
+ def self.parse_explicit_navigation_args
23
+ args = if explicit_navigation_args.empty?
24
+ [{}]
25
+ else
26
+ explicit_navigation_args
27
+ end
28
+ indexed_args = args_indexed_by_level(args)
29
+ deepest = deepest_level_and_item(indexed_args)
14
30
 
15
- # If any navigation has been explicitely set in the controller this method evaluates the specified args set in the controller and sets
16
- # the correct instance variable in the controller.
17
- def handle_explicit_navigation
18
- if SimpleNavigation.explicit_navigation_args
19
- level, navigation = parse_explicit_navigation_args
20
- self.adapter.controller.instance_variable_set(:"@sn_current_navigation_#{level}", navigation)
21
- end
31
+ if deepest.first.zero?
32
+ fail ArgumentError, 'Invalid level specified or item key not found'
22
33
  end
23
34
 
24
- # TODO: refactor this ugly thing to make it nice and short
25
- def parse_explicit_navigation_args
26
- args = SimpleNavigation.explicit_navigation_args
27
- args = [Hash.new] if args.empty?
28
- if args.first.kind_of? Hash
29
- options = args.first
30
- else # args is a list of current navigation for several levels
31
- options = {}
32
- if args.size == 1 #only one navi-key has been specified, try to find out level
33
- level = SimpleNavigation.primary_navigation.level_for_item(args.first)
34
- options[:"level_#{level}"] = args.first if level
35
- else
36
- args.each_with_index {|arg, i| options[:"level_#{i + 1}"] = arg}
37
- end
38
- end
39
- #only the deepest level is relevant
40
- level = options.inject(0) do |max, kv|
41
- kv.first.to_s =~ /level_(\d)/
42
- max = $1.to_i if $1.to_i > max
43
- max
44
- end
45
- raise ArgumentError, "Invalid level specified or item key not found" if level == 0
46
- [level, options[:"level_#{level}"]]
35
+ deepest
36
+ end
37
+
38
+ private
39
+
40
+ def self.deepest_level_and_item(navigation_args)
41
+ navigation_args.map { |k, v| [k.to_s[/level_(\d)/, 1].to_i, v] }
42
+ .max
43
+ end
44
+
45
+ def self.args_indexed_by_level(navigation_args)
46
+ if navigation_args.first.is_a?(Hash)
47
+ navigation_args.first
48
+ elsif navigation_args.size == 1
49
+ level = primary_navigation.level_for_item(navigation_args.first)
50
+ level ? { :"level_#{level}" => navigation_args.first } : {}
51
+ else
52
+ navigation_args.each_with_index
53
+ .with_object({}) do |(arg, i), h|
54
+ h[:"level_#{i + 1}"] = arg
55
+ end
47
56
  end
48
-
49
- end
50
-
51
- # Adds methods for explicitely setting the current 'active' navigation to the controllers.
52
- # Since version 2.0.0 the simple_navigation plugin determines the active navigation based on the current url by default (auto highlighting),
53
- # so explicitely defining the active navigation in the controllers is only needed for edge cases where automatic highlighting does not work.
54
- #
55
- # On the controller class level, use the <tt>navigation</tt> method to set the active navigation for all actions in the controller.
56
- # Let's assume that we have a primary navigation item :account which in turn has a sub navigation item :settings.
57
- #
57
+ end
58
+
59
+ # Adds methods for explicitely setting the current 'active' navigation to
60
+ # the controllers.
61
+ # Since version 2.0.0 the simple_navigation plugin determines the active
62
+ # navigation based on the current url by default (auto highlighting),
63
+ # so explicitely defining the active navigation in the controllers is only
64
+ # needed for edge cases where automatic highlighting does not work.
65
+ #
66
+ # On the controller class level, use the <tt>navigation</tt> method to set the
67
+ # active navigation for all actions in the controller.
68
+ # Let's assume that we have a primary navigation item :account which in turn
69
+ # has a sub navigation item :settings.
70
+ #
58
71
  # ==== Examples
59
72
  # class AccountController << ActionController
60
73
  # navigation :account
@@ -66,28 +79,38 @@ module SimpleNavigation
66
79
  # ...
67
80
  # end
68
81
  #
69
- # The first example sets the current primary navigation to :account for all actions. No active sub_navigation.
70
- # The second example sets the current sub navigation to :settings and since it is a child of :account the current primary navigation is set to :account.
71
- #
72
- # On the controller instance level, use the <tt>current_navigation</tt> method to define the active navigation for a specific action.
73
- # The navigation item that is set in <tt>current_navigation</tt> overrides the one defined on the controller class level (see <tt>navigation</tt> method).
74
- # Thus if you have an :account primary item with a :special sub navigation item:
82
+ # The first example sets the current primary navigation to :account for all
83
+ # actions. No active sub_navigation.
84
+ # The second example sets the current sub navigation to :settings and since
85
+ # it is a child of :account the current primary navigation is set to :account.
86
+ #
87
+ # On the controller instance level, use the <tt>current_navigation</tt> method
88
+ # to define the active navigation for a specific action.
89
+ # The navigation item that is set in <tt>current_navigation</tt> overrides the
90
+ # one defined on the controller class level (see <tt>navigation</tt> method).
91
+ # Thus if you have an :account primary item with a :special
92
+ # sub navigation item:
75
93
  #
76
94
  # ==== Example
77
95
  # class AccountController << ActionController
78
96
  # navigation :account
79
- #
97
+ #
80
98
  # def your_special_action
81
99
  # ...
82
100
  # current_navigation :special
83
101
  # end
84
102
  # end
85
103
  #
86
- # The code above still sets the active primary navigation to :account for all actions, but sets the sub_navigation to :account -> :special for 'your_special_action'.
104
+ # The code above still sets the active primary navigation to :account for all
105
+ # actions, but sets the sub_navigation to :account -> :special for
106
+ # 'your_special_action'.
87
107
  #
88
- # Note 1: As you can see above you just have to set the navigation item of your 'deepest' navigation level as active and all its parents are marked as active, too.
108
+ # Note 1: As you can see above you just have to set the navigation item of
109
+ # your 'deepest' navigation level as active and all its parents are
110
+ # marked as active, too.
89
111
  #
90
- # Note 2: The specified symbols must match the keys for your navigation items in your config/navigation.rb file.
112
+ # Note 2: The specified symbols must match the keys for your navigation
113
+ # items in your config/navigation.rb file.
91
114
  module ControllerMethods
92
115
  def self.included(base) #:nodoc:
93
116
  base.class_eval do
@@ -95,13 +118,14 @@ module SimpleNavigation
95
118
  include InstanceMethods
96
119
  end
97
120
  end
98
-
121
+
99
122
  module ClassMethods
100
123
  # Sets the active navigation for all actions in this controller.
101
124
  #
102
- # The specified symbol must match the keys for your navigation items in your config/navigation.rb file.
125
+ # The specified symbol must match the keys for your navigation items
126
+ # in your config/navigation.rb file.
103
127
  def navigation(*args)
104
- self.class_eval do
128
+ class_eval do
105
129
  define_method :sn_set_navigation do
106
130
  current_navigation(*args)
107
131
  end
@@ -110,35 +134,31 @@ module SimpleNavigation
110
134
  end
111
135
  end
112
136
  end
113
-
137
+
114
138
  module InstanceMethods
115
- # Sets the active navigation. Call this method in any action to override the controller-wide active navigation
116
- # specified by navigation.
139
+ # Sets the active navigation. Call this method in any action to override
140
+ # the controller-wide active navigation specified by navigation.
117
141
  #
118
- # The specified symbol must match the keys for your navigation items in your config/navigation.rb file.
142
+ # The specified symbol must match the keys for your navigation items in
143
+ # your config/navigation.rb file.
119
144
  def current_navigation(*args)
120
145
  @sn_current_navigation_args = args
121
146
  end
122
147
  end
123
-
124
148
  end
125
-
149
+
126
150
  class Item
127
-
128
151
  def selected_by_config?
129
- key == SimpleNavigation.current_navigation_for(@container.level)
152
+ key == SimpleNavigation.current_navigation_for(container.level)
130
153
  end
131
-
132
154
  end
133
-
155
+
134
156
  class ItemContainer
135
-
136
157
  def selected_item
137
- self[SimpleNavigation.current_navigation_for(self.level)] || items.find {|i| i.selected?}
158
+ self[SimpleNavigation.current_navigation_for(level)] ||
159
+ items.find(&:selected?)
138
160
  end
139
-
140
161
  end
141
-
142
162
  end
143
-
144
- ActionController::Base.send(:include, SimpleNavigation::ControllerMethods)
163
+
164
+ ActionController::Base.send(:include, SimpleNavigation::ControllerMethods)