simple-navigation 3.12.0 → 3.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +4 -0
- data/generators/navigation_config/navigation_config_generator.rb +3 -3
- data/generators/navigation_config/templates/config/navigation.rb +9 -10
- data/init.rb +1 -1
- data/lib/generators/navigation_config/navigation_config_generator.rb +11 -6
- data/lib/simple-navigation.rb +1 -1
- data/lib/simple_navigation.rb +93 -65
- data/lib/simple_navigation/adapters/base.rb +16 -16
- data/lib/simple_navigation/adapters/nanoc.rb +7 -6
- data/lib/simple_navigation/adapters/padrino.rb +5 -7
- data/lib/simple_navigation/adapters/rails.rb +52 -39
- data/lib/simple_navigation/adapters/sinatra.rb +14 -17
- data/lib/simple_navigation/core/configuration.rb +73 -34
- data/lib/simple_navigation/core/item.rb +110 -54
- data/lib/simple_navigation/core/item_adapter.rb +18 -13
- data/lib/simple_navigation/core/item_container.rb +93 -66
- data/lib/simple_navigation/core/items_provider.rb +12 -10
- data/lib/simple_navigation/rails_controller_methods.rb +98 -78
- data/lib/simple_navigation/rendering/helpers.rb +130 -68
- data/lib/simple_navigation/rendering/renderer/base.rb +30 -25
- data/lib/simple_navigation/rendering/renderer/breadcrumbs.rb +26 -19
- data/lib/simple_navigation/rendering/renderer/json.rb +11 -13
- data/lib/simple_navigation/rendering/renderer/links.rb +18 -13
- data/lib/simple_navigation/rendering/renderer/list.rb +28 -15
- data/lib/simple_navigation/rendering/renderer/text.rb +7 -12
- data/lib/simple_navigation/version.rb +1 -1
- data/spec/lib/simple_navigation/core/item_adapter_spec.rb +1 -1
- data/spec/lib/simple_navigation/core/item_container_spec.rb +118 -68
- data/spec/lib/simple_navigation_spec.rb +16 -5
- metadata +2 -2
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
|
3
3
|
module SimpleNavigation
|
4
|
-
|
5
|
-
#
|
6
|
-
# When defining the items that way, every item you provide needs to define
|
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
|
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.
|
18
|
-
# The hashes
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
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.
|
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.
|
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
|
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
|
33
|
-
# proc should evaluate to a true or false value and is evaluated
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
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
|
-
|
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=(
|
48
|
-
items.
|
49
|
-
|
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 {|
|
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
|
62
|
-
#
|
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
|
-
|
66
|
-
|
67
|
-
items.each do |
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
79
|
-
|
80
|
-
|
81
|
-
|
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?
|
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
|
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
|
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
|
-
|
109
|
-
|
110
|
-
|
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
|
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
|
-
|
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
|
-
|
169
|
+
[options.delete(:unless)].flatten.compact.none? { |m| evaluate_method(m) }
|
138
170
|
end
|
139
171
|
|
140
|
-
|
141
|
-
def evaluate_method(method) #:nodoc:
|
172
|
+
def evaluate_method(method)
|
142
173
|
case method
|
143
|
-
|
144
|
-
|
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
|
-
#
|
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
|
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
|
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.
|
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
|
-
|
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
|
-
|
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
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
16
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
50
|
-
|
51
|
-
#
|
52
|
-
# Since version 2.0.0 the simple_navigation plugin determines the active
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
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
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
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
|
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(
|
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(
|
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)
|