simple-navigation 3.0.2 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,6 @@
1
+ *3.1.0
2
+ * added new helper method 'active_navigation_item_name' to render the name of the currently active item
3
+
1
4
  *3.0.2
2
5
 
3
6
  * dom_id and dom_class can now be set as option in the item's definition (useful for dynamic menu items).
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.2
1
+ 3.1.0
@@ -113,6 +113,7 @@ module SimpleNavigation
113
113
 
114
114
  # Returns the active item container for the specified level. Valid levels are
115
115
  # * :all - in this case the primary_navigation is returned.
116
+ # * :leaves - the 'deepest' active item_container will be returned
116
117
  # * a specific level - the active item_container for the specified level will be returned
117
118
  # * a range of levels - the active item_container for the range's minimum will be returned
118
119
  #
@@ -121,6 +122,8 @@ module SimpleNavigation
121
122
  case level
122
123
  when :all
123
124
  self.primary_navigation
125
+ when :leaves
126
+ self.primary_navigation.active_leaf_container
124
127
  when Integer
125
128
  self.primary_navigation.active_item_container_for(level)
126
129
  when Range
@@ -142,7 +145,15 @@ module SimpleNavigation
142
145
  # render_navigation(:renderer => :my_renderer)
143
146
  def register_renderer(renderer_hash)
144
147
  self.registered_renderers.merge!(renderer_hash)
145
- end
148
+ end
149
+
150
+ private
151
+
152
+ def apply_defaults(options)
153
+ options[:level] = options.delete(:levels) if options[:levels]
154
+ {:context => :default, :level => :all}.merge(options)
155
+ end
156
+
146
157
 
147
158
  end
148
159
 
@@ -8,6 +8,7 @@ module SimpleNavigation
8
8
  SimpleNavigation.set_env(rails_root, rails_env)
9
9
  ActionController::Base.send(:include, SimpleNavigation::Helpers)
10
10
  ActionController::Base.send(:helper_method, :render_navigation)
11
+ ActionController::Base.send(:helper_method, :active_navigation_item_name)
11
12
  end
12
13
 
13
14
  def initialize(context)
@@ -103,6 +103,16 @@ module SimpleNavigation
103
103
  return nil unless selected_sub_navigation?
104
104
  return selected_item.sub_navigation.active_item_container_for(desired_level)
105
105
  end
106
+
107
+ # Returns the deepest possible active item_container.
108
+ # (recursively searches in the sub_navigation if this container has a selected sub_navigation).
109
+ def active_leaf_container
110
+ if selected_sub_navigation?
111
+ selected_item.sub_navigation.active_leaf_container
112
+ else
113
+ self
114
+ end
115
+ end
106
116
 
107
117
  # Returns true if there are no items defined for this container.
108
118
  def empty?
@@ -33,6 +33,37 @@ module SimpleNavigation
33
33
  # * <tt>:renderer</tt> - specify the renderer to be used for rendering the navigation. Either provide the Class or a symbol matching a registered renderer. Defaults to :list (html list renderer).
34
34
  def render_navigation(options={})
35
35
  options = apply_defaults(options)
36
+ load_config(options)
37
+ active_item_container = SimpleNavigation.active_item_container_for(options[:level])
38
+ active_item_container.render(options) unless active_item_container.nil?
39
+ end
40
+
41
+ # Returns the name of the currently active navigation item belonging to the specified level.
42
+ #
43
+ # The following options are supported:
44
+ # * <tt>:level</tt> - defaults to :all which returns the most specific/deepest selected item (the leaf).
45
+ # Specify a specific level to only look for the selected item in the specified level of navigation (e.g. :level => 1 for primary_navigation etc...).
46
+ # * <tt>:context</tt> - specifies the context for which you would like to find the active navigation item. Defaults to :default which loads the default navigation.rb (i.e. config/navigation.rb).
47
+ # If you specify a context then the plugin tries to load the configuration file for that context, e.g. if you call <tt>active_navigation_item_name(:context => :admin)</tt> the file config/admin_navigation.rb
48
+ # will be loaded and used for searching the active item.
49
+ # * <tt>:items</tt> - you can specify the items directly (e.g. if items are dynamically generated from database). See SimpleNavigation::ItemsProvider for documentation on what to provide as items.
50
+ #
51
+ # Returns an empty string if no active item can be found for the specified options
52
+ def active_navigation_item_name(options={})
53
+ options = apply_defaults(options)
54
+ load_config(options)
55
+ options[:level] = :leaves if options[:level] == :all
56
+ active_item_container = SimpleNavigation.active_item_container_for(options[:level])
57
+ if active_item_container && !active_item_container.selected_item.nil?
58
+ active_item_container.selected_item.name
59
+ else
60
+ ''
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def load_config(options)
36
67
  ctx = options.delete(:context)
37
68
  SimpleNavigation.init_adapter_from self
38
69
  SimpleNavigation.load_config(ctx)
@@ -40,12 +71,8 @@ module SimpleNavigation
40
71
  SimpleNavigation.config.items(options[:items]) if options[:items]
41
72
  SimpleNavigation.handle_explicit_navigation if SimpleNavigation.respond_to?(:handle_explicit_navigation)
42
73
  raise "no primary navigation defined, either use a navigation config file or pass items directly to render_navigation" unless SimpleNavigation.primary_navigation
43
- active_item_container = SimpleNavigation.active_item_container_for(options[:level])
44
- active_item_container.render(options) unless active_item_container.nil?
45
74
  end
46
75
 
47
- private
48
-
49
76
  def apply_defaults(options)
50
77
  options[:level] = options.delete(:levels) if options[:levels]
51
78
  {:context => :default, :level => :all}.merge(options)
@@ -29,6 +29,7 @@ describe SimpleNavigation::Adapters::Rails do
29
29
  end
30
30
  it "should install the helper methods in the controller" do
31
31
  ActionController::Base.should_receive(:helper_method).with(:render_navigation)
32
+ ActionController::Base.should_receive(:helper_method).with(:active_navigation_item_name)
32
33
  SimpleNavigation.register
33
34
  end
34
35
 
@@ -152,6 +152,30 @@ describe SimpleNavigation::ItemContainer do
152
152
  end
153
153
  end
154
154
  end
155
+
156
+ describe 'active_leaf_container' do
157
+ context 'the current container has a selected subnavigation' do
158
+ before(:each) do
159
+ @item_container.stub!(:selected_sub_navigation? => true)
160
+ @sub_nav = stub(:sub_nav)
161
+ @selected_item = stub(:selected_item)
162
+ @item_container.stub!(:selected_item => @selected_item)
163
+ @selected_item.stub!(:sub_navigation => @sub_nav)
164
+ end
165
+ it "should call recursively on the sub_navigation" do
166
+ @sub_nav.should_receive(:active_leaf_container)
167
+ @item_container.active_leaf_container
168
+ end
169
+ end
170
+ context 'the current container is the leaf already' do
171
+ before(:each) do
172
+ @item_container.stub!(:selected_sub_navigation? => false)
173
+ end
174
+ it "should return itsself" do
175
+ @item_container.active_leaf_container.should == @item_container
176
+ end
177
+ end
178
+ end
155
179
 
156
180
  describe 'item' do
157
181
 
@@ -5,7 +5,15 @@ describe SimpleNavigation::Helpers do
5
5
  include SimpleNavigation::Helpers
6
6
  end
7
7
 
8
- before(:each) do
8
+ def blackbox_setup()
9
+ @controller = ControllerMock.new
10
+ @controller.stub!(:load_config)
11
+ setup_adapter_for :rails
12
+ primary_navigation = primary_container
13
+ SimpleNavigation.stub!(:primary_navigation => primary_navigation)
14
+ end
15
+
16
+ def whitebox_setup
9
17
  @controller = ControllerMock.new
10
18
  SimpleNavigation.stub!(:load_config)
11
19
  SimpleNavigation::Configuration.stub!(:eval_config)
@@ -14,8 +22,35 @@ describe SimpleNavigation::Helpers do
14
22
  SimpleNavigation.stub!(:config_file? => true)
15
23
  end
16
24
 
17
- describe 'render_navigation' do
25
+ describe 'active_navigation_item_name' do
26
+ before(:each) do
27
+ blackbox_setup
28
+ end
29
+ context 'active item_container for desired level exists' do
30
+ context 'container has selected item' do
31
+ before(:each) do
32
+ select_item(:subnav1)
33
+ end
34
+ it {@controller.active_navigation_item_name(:level => 2).should == 'subnav1'}
35
+ it {@controller.active_navigation_item_name.should == 'subnav1'}
36
+ it {@controller.active_navigation_item_name(:level => 1).should == 'invoices'}
37
+ it {@controller.active_navigation_item_name(:level => :all).should == 'subnav1'}
38
+ end
39
+ context 'container does not have selected item' do
40
+ it {@controller.active_navigation_item_name.should == ''}
41
+ end
42
+ end
43
+ context 'no active item_container for desired level' do
44
+ it {@controller.active_navigation_item_name(:level => 5).should == ''}
45
+ end
46
+ end
18
47
 
48
+ describe 'render_navigation' do
49
+
50
+ before(:each) do
51
+ whitebox_setup
52
+ end
53
+
19
54
  describe 'regarding loading of the config-file' do
20
55
  context 'no options specified' do
21
56
  it "should load the config-file for the default context" do
@@ -23,7 +58,7 @@ describe SimpleNavigation::Helpers do
23
58
  @controller.render_navigation
24
59
  end
25
60
  end
26
-
61
+
27
62
  context 'with options specified' do
28
63
  it "should load the config-file for the specified context" do
29
64
  SimpleNavigation.should_receive(:load_config).with(:my_context)
@@ -31,12 +66,12 @@ describe SimpleNavigation::Helpers do
31
66
  end
32
67
  end
33
68
  end
34
-
69
+
35
70
  it "should eval the config on every request" do
36
71
  SimpleNavigation::Configuration.should_receive(:eval_config).with(:default)
37
72
  @controller.render_navigation
38
73
  end
39
-
74
+
40
75
  describe 'regarding setting of items' do
41
76
  context 'not items specified in options' do
42
77
  it "should not set the items directly" do
@@ -54,14 +89,14 @@ describe SimpleNavigation::Helpers do
54
89
  end
55
90
  end
56
91
  end
57
-
92
+
58
93
  describe 'no primary navigation defined' do
59
94
  before(:each) do
60
95
  SimpleNavigation.stub!(:primary_navigation => nil)
61
96
  end
62
97
  it {lambda {@controller.render_navigation}.should raise_error}
63
98
  end
64
-
99
+
65
100
  context 'rendering of the item_container' do
66
101
  before(:each) do
67
102
  @active_item_container = stub(:item_container).as_null_object
@@ -87,14 +122,14 @@ describe SimpleNavigation::Helpers do
87
122
  end
88
123
  end
89
124
  end
90
-
125
+
91
126
  context 'primary' do
92
127
  it "should call render on the primary_navigation (specifying level through options)" do
93
128
  @primary_navigation.should_receive(:render).with(:level => 1)
94
129
  @controller.render_navigation(:level => 1)
95
130
  end
96
131
  end
97
-
132
+
98
133
  context 'secondary' do
99
134
  context 'with current_primary_navigation set' do
100
135
  before(:each) do
@@ -122,18 +157,20 @@ describe SimpleNavigation::Helpers do
122
157
  lambda {@controller.render_navigation(:level => 2)}.should_not raise_error
123
158
  end
124
159
  end
125
-
160
+
126
161
  end
127
-
162
+
128
163
  context 'unknown level' do
129
164
  it "should raise an error" do
130
165
  lambda {@controller.render_navigation(:level => :unknown)}.should raise_error(ArgumentError)
131
166
  end
132
167
  end
168
+
133
169
  end
134
-
170
+
135
171
  describe "should treat :level and :levels options the same" do
136
172
  before(:each) do
173
+ whitebox_setup
137
174
  @selected_item_container = stub(:selected_container).as_null_object
138
175
  SimpleNavigation.stub!(:active_item_container_for => @selected_item_container)
139
176
  end
@@ -255,6 +255,12 @@ describe SimpleNavigation do
255
255
  SimpleNavigation.active_item_container_for(:all).should == @primary
256
256
  end
257
257
  end
258
+ context 'level is :leaves' do
259
+ it "should return the currently active leaf-container" do
260
+ @primary.should_receive(:active_leaf_container)
261
+ SimpleNavigation.active_item_container_for(:leaves)
262
+ end
263
+ end
258
264
  context 'level is a Range' do
259
265
  it "should take the min of the range to lookup the active container" do
260
266
  @primary.should_receive(:active_item_container_for).with(2)
data/spec/spec_helper.rb CHANGED
@@ -48,7 +48,7 @@ def primary_items
48
48
  end
49
49
 
50
50
  def primary_container
51
- container = SimpleNavigation::ItemContainer.new(0)
51
+ container = SimpleNavigation::ItemContainer.new(1)
52
52
  container.dom_id = 'nav_dom_id'
53
53
  container.dom_class = 'nav_dom_class'
54
54
  @items = primary_items.map {|params| SimpleNavigation::Item.new(container, *params)}
@@ -74,7 +74,7 @@ def select_item(key)
74
74
  end
75
75
 
76
76
  def subnav_container
77
- container = SimpleNavigation::ItemContainer.new(1)
77
+ container = SimpleNavigation::ItemContainer.new(2)
78
78
  items = sub_items.map {|params| SimpleNavigation::Item.new(container, *params)}
79
79
  items.each {|i| i.stub!(:selected? => false)}
80
80
  container.instance_variable_set(:@items, items)
@@ -82,10 +82,15 @@ def subnav_container
82
82
  end
83
83
 
84
84
  def setup_renderer_for(renderer_class, framework, options)
85
+ setup_adapter_for framework
86
+ @renderer = renderer_class.new(options)
87
+ end
88
+
89
+ def setup_adapter_for(framework)
85
90
  adapter = case framework
86
91
  when :rails
87
92
  SimpleNavigation::Adapters::Rails.new(stub(:context, :view_context => ActionView::Base.new))
88
93
  end
89
94
  SimpleNavigation.stub!(:adapter => adapter)
90
- @renderer = renderer_class.new(options)
95
+ adapter
91
96
  end
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  prerelease: false
6
6
  segments:
7
7
  - 3
8
+ - 1
8
9
  - 0
9
- - 2
10
- version: 3.0.2
10
+ version: 3.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andi Schacke
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-01 00:00:00 +01:00
18
+ date: 2010-12-27 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency