##// END OF EJS Templates
Fixes menu translation....
Jean-Philippe Lang -
r2434:9819a6bfd1bf
parent child
Show More
@@ -1,216 +1,219
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 module Redmine
19 19 module MenuManager
20 20 module MenuController
21 21 def self.included(base)
22 22 base.extend(ClassMethods)
23 23 end
24 24
25 25 module ClassMethods
26 26 @@menu_items = Hash.new {|hash, key| hash[key] = {:default => key, :actions => {}}}
27 27 mattr_accessor :menu_items
28 28
29 29 # Set the menu item name for a controller or specific actions
30 30 # Examples:
31 31 # * menu_item :tickets # => sets the menu name to :tickets for the whole controller
32 32 # * menu_item :tickets, :only => :list # => sets the menu name to :tickets for the 'list' action only
33 33 # * menu_item :tickets, :only => [:list, :show] # => sets the menu name to :tickets for 2 actions only
34 34 #
35 35 # The default menu item name for a controller is controller_name by default
36 36 # Eg. the default menu item name for ProjectsController is :projects
37 37 def menu_item(id, options = {})
38 38 if actions = options[:only]
39 39 actions = [] << actions unless actions.is_a?(Array)
40 40 actions.each {|a| menu_items[controller_name.to_sym][:actions][a.to_sym] = id}
41 41 else
42 42 menu_items[controller_name.to_sym][:default] = id
43 43 end
44 44 end
45 45 end
46 46
47 47 def menu_items
48 48 self.class.menu_items
49 49 end
50 50
51 51 # Returns the menu item name according to the current action
52 52 def current_menu_item
53 53 @current_menu_item ||= menu_items[controller_name.to_sym][:actions][action_name.to_sym] ||
54 54 menu_items[controller_name.to_sym][:default]
55 55 end
56 56
57 57 # Redirects user to the menu item of the given project
58 58 # Returns false if user is not authorized
59 59 def redirect_to_project_menu_item(project, name)
60 60 item = Redmine::MenuManager.items(:project_menu).detect {|i| i.name.to_s == name.to_s}
61 61 if item && User.current.allowed_to?(item.url, project) && (item.condition.nil? || item.condition.call(project))
62 62 redirect_to({item.param => project}.merge(item.url))
63 63 return true
64 64 end
65 65 false
66 66 end
67 67 end
68 68
69 69 module MenuHelper
70 70 # Returns the current menu item name
71 71 def current_menu_item
72 72 @controller.current_menu_item
73 73 end
74 74
75 75 # Renders the application main menu
76 76 def render_main_menu(project)
77 77 render_menu((project && !project.new_record?) ? :project_menu : :application_menu, project)
78 78 end
79 79
80 80 def render_menu(menu, project=nil)
81 81 links = []
82 82 menu_items_for(menu, project) do |item, caption, url, selected|
83 83 links << content_tag('li',
84 84 link_to(h(caption), url, item.html_options(:selected => selected)))
85 85 end
86 86 links.empty? ? nil : content_tag('ul', links.join("\n"))
87 87 end
88 88
89 89 def menu_items_for(menu, project=nil)
90 90 items = []
91 91 Redmine::MenuManager.allowed_items(menu, User.current, project).each do |item|
92 92 unless item.condition && !item.condition.call(project)
93 93 url = case item.url
94 94 when Hash
95 95 project.nil? ? item.url : {item.param => project}.merge(item.url)
96 96 when Symbol
97 97 send(item.url)
98 98 else
99 99 item.url
100 100 end
101 101 caption = item.caption(project)
102 caption = l_or_humanize(caption, :prefix => 'label_') if caption.is_a?(Symbol)
103 102 if block_given?
104 103 yield item, caption, url, (current_menu_item == item.name)
105 104 else
106 105 items << [item, caption, url, (current_menu_item == item.name)]
107 106 end
108 107 end
109 108 end
110 109 return block_given? ? nil : items
111 110 end
112 111 end
113 112
114 113 class << self
115 114 def map(menu_name)
116 115 @items ||= {}
117 116 mapper = Mapper.new(menu_name.to_sym, @items)
118 117 if block_given?
119 118 yield mapper
120 119 else
121 120 mapper
122 121 end
123 122 end
124 123
125 124 def items(menu_name)
126 125 @items[menu_name.to_sym] || []
127 126 end
128 127
129 128 def allowed_items(menu_name, user, project)
130 129 project ? items(menu_name).select {|item| user && user.allowed_to?(item.url, project)} : items(menu_name)
131 130 end
132 131 end
133 132
134 133 class Mapper
135 134 def initialize(menu, items)
136 135 items[menu] ||= []
137 136 @menu = menu
138 137 @menu_items = items[menu]
139 138 end
140 139
141 140 @@last_items_count = Hash.new {|h,k| h[k] = 0}
142 141
143 142 # Adds an item at the end of the menu. Available options:
144 143 # * param: the parameter name that is used for the project id (default is :id)
145 144 # * if: a Proc that is called before rendering the item, the item is displayed only if it returns true
146 145 # * caption that can be:
147 146 # * a localized string Symbol
148 147 # * a String
149 148 # * a Proc that can take the project as argument
150 149 # * before, after: specify where the menu item should be inserted (eg. :after => :activity)
151 150 # * last: menu item will stay at the end (eg. :last => true)
152 151 # * html_options: a hash of html options that are passed to link_to
153 152 def push(name, url, options={})
154 153 options = options.dup
155 154
156 155 # menu item position
157 156 if before = options.delete(:before)
158 157 position = @menu_items.collect(&:name).index(before)
159 158 elsif after = options.delete(:after)
160 159 position = @menu_items.collect(&:name).index(after)
161 160 position += 1 unless position.nil?
162 161 elsif options.delete(:last)
163 162 position = @menu_items.size
164 163 @@last_items_count[@menu] += 1
165 164 end
166 165 # default position
167 166 position ||= @menu_items.size - @@last_items_count[@menu]
168 167
169 168 @menu_items.insert(position, MenuItem.new(name, url, options))
170 169 end
171 170
172 171 # Removes a menu item
173 172 def delete(name)
174 173 @menu_items.delete_if {|i| i.name == name}
175 174 end
176 175 end
177 176
178 177 class MenuItem
179 178 include Redmine::I18n
180 179 attr_reader :name, :url, :param, :condition
181 180
182 181 def initialize(name, url, options)
183 182 raise "Invalid option :if for menu item '#{name}'" if options[:if] && !options[:if].respond_to?(:call)
184 183 raise "Invalid option :html for menu item '#{name}'" if options[:html] && !options[:html].is_a?(Hash)
185 184 @name = name
186 185 @url = url
187 186 @condition = options[:if]
188 187 @param = options[:param] || :id
189 @caption = options[:caption] || @name
188 @caption = options[:caption]
190 189 @html_options = options[:html] || {}
191 190 # Adds a unique class to each menu item based on its name
192 191 @html_options[:class] = [@html_options[:class], @name.to_s.dasherize].compact.join(' ')
193 192 end
194 193
195 194 def caption(project=nil)
196 195 if @caption.is_a?(Proc)
197 196 c = @caption.call(project).to_s
198 197 c = @name.to_s.humanize if c.blank?
199 198 c
200 199 else
201 @caption
200 if @caption.nil?
201 l_or_humanize(name, :prefix => 'label_')
202 else
203 @caption.is_a?(Symbol) ? l(@caption) : @caption
204 end
202 205 end
203 206 end
204 207
205 208 def html_options(options={})
206 209 if options[:selected]
207 210 o = @html_options.dup
208 211 o[:class] += ' selected'
209 212 o
210 213 else
211 214 @html_options
212 215 end
213 216 end
214 217 end
215 218 end
216 219 end
General Comments 0
You need to be logged in to leave comments. Login now