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