##// END OF EJS Templates
Menu mapper: add support for :before, :after and :last options to #push method and add #delete method....
Jean-Philippe Lang -
r1646:7b8a4fc28bd2
parent child
Show More
@@ -130,5 +130,5 Redmine::MenuManager.map :project_menu do |menu|
130 menu.push :files, { :controller => 'projects', :action => 'list_files' }, :caption => :label_attachment_plural
130 menu.push :files, { :controller => 'projects', :action => 'list_files' }, :caption => :label_attachment_plural
131 menu.push :repository, { :controller => 'repositories', :action => 'show' },
131 menu.push :repository, { :controller => 'repositories', :action => 'show' },
132 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
132 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
133 menu.push :settings, { :controller => 'projects', :action => 'settings' }
133 menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
134 end
134 end
@@ -92,11 +92,9 module Redmine
92
92
93 class << self
93 class << self
94 def map(menu_name)
94 def map(menu_name)
95 mapper = Mapper.new
96 yield mapper
97 @items ||= {}
95 @items ||= {}
98 @items[menu_name.to_sym] ||= []
96 mapper = Mapper.new(menu_name.to_sym, @items)
99 @items[menu_name.to_sym] += mapper.items
97 yield mapper
100 end
98 end
101
99
102 def items(menu_name)
100 def items(menu_name)
@@ -109,6 +107,14 module Redmine
109 end
107 end
110
108
111 class Mapper
109 class Mapper
110 def initialize(menu, items)
111 items[menu] ||= []
112 @menu = menu
113 @menu_items = items[menu]
114 end
115
116 @@last_items_count = Hash.new {|h,k| h[k] = 0}
117
112 # Adds an item at the end of the menu. Available options:
118 # Adds an item at the end of the menu. Available options:
113 # * param: the parameter name that is used for the project id (default is :id)
119 # * param: the parameter name that is used for the project id (default is :id)
114 # * if: a Proc that is called before rendering the item, the item is displayed only if it returns true
120 # * if: a Proc that is called before rendering the item, the item is displayed only if it returns true
@@ -116,13 +122,31 module Redmine
116 # * a localized string Symbol
122 # * a localized string Symbol
117 # * a String
123 # * a String
118 # * a Proc that can take the project as argument
124 # * a Proc that can take the project as argument
125 # * before, after: specify where the menu item should be inserted (eg. :after => :activity)
126 # * last: menu item will stay at the end (eg. :last => true)
119 # * html_options: a hash of html options that are passed to link_to
127 # * html_options: a hash of html options that are passed to link_to
120 def push(name, url, options={})
128 def push(name, url, options={})
121 items << MenuItem.new(name, url, options)
129 options = options.dup
130
131 # menu item position
132 if before = options.delete(:before)
133 position = @menu_items.index {|i| i.name == before}
134 elsif after = options.delete(:after)
135 position = @menu_items.index {|i| i.name == after}
136 position += 1 unless position.nil?
137 elsif options.delete(:last)
138 position = @menu_items.size
139 @@last_items_count[@menu] += 1
140 end
141 # default position
142 position ||= @menu_items.size - @@last_items_count[@menu]
143
144 @menu_items.insert(position, MenuItem.new(name, url, options))
122 end
145 end
123
146
124 def items
147 # Removes a menu item
125 @items ||= []
148 def delete(name)
149 @menu_items.delete_if {|i| i.name == name}
126 end
150 end
127 end
151 end
128
152
@@ -312,4 +312,33 class ProjectsControllerTest < Test::Unit::TestCase
312 assert_redirected_to 'admin/projects'
312 assert_redirected_to 'admin/projects'
313 assert Project.find(1).active?
313 assert Project.find(1).active?
314 end
314 end
315
316 def test_project_menu
317 assert_no_difference 'Redmine::MenuManager.items(:project_menu).size' do
318 Redmine::MenuManager.map :project_menu do |menu|
319 menu.push :foo, { :controller => 'projects', :action => 'show' }, :cation => 'Foo'
320 menu.push :bar, { :controller => 'projects', :action => 'show' }, :before => :activity
321 menu.push :hello, { :controller => 'projects', :action => 'show' }, :caption => Proc.new {|p| p.name.upcase }, :after => :bar
322 end
323
324 get :show, :id => 1
325 assert_tag :div, :attributes => { :id => 'main-menu' },
326 :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'Foo' } }
327
328 assert_tag :div, :attributes => { :id => 'main-menu' },
329 :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'Bar' },
330 :before => { :tag => 'li', :child => { :tag => 'a', :content => 'ECOOKBOOK' } } }
331
332 assert_tag :div, :attributes => { :id => 'main-menu' },
333 :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'ECOOKBOOK' },
334 :before => { :tag => 'li', :child => { :tag => 'a', :content => 'Activity' } } }
335
336 # Remove the menu items
337 Redmine::MenuManager.map :project_menu do |menu|
338 menu.delete :foo
339 menu.delete :bar
340 menu.delete :hello
341 end
342 end
343 end
315 end
344 end
General Comments 0
You need to be logged in to leave comments. Login now