##// END OF EJS Templates
Missing html_safe....
Jean-Philippe Lang -
r8270:38843eb7aa31
parent child
Show More
@@ -1,438 +1,438
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 module Redmine
18 module Redmine
19 module MenuManager
19 module MenuManager
20 class MenuError < StandardError #:nodoc:
20 class MenuError < StandardError #:nodoc:
21 end
21 end
22
22
23 module MenuController
23 module MenuController
24 def self.included(base)
24 def self.included(base)
25 base.extend(ClassMethods)
25 base.extend(ClassMethods)
26 end
26 end
27
27
28 module ClassMethods
28 module ClassMethods
29 @@menu_items = Hash.new {|hash, key| hash[key] = {:default => key, :actions => {}}}
29 @@menu_items = Hash.new {|hash, key| hash[key] = {:default => key, :actions => {}}}
30 mattr_accessor :menu_items
30 mattr_accessor :menu_items
31
31
32 # Set the menu item name for a controller or specific actions
32 # Set the menu item name for a controller or specific actions
33 # Examples:
33 # Examples:
34 # * menu_item :tickets # => sets the menu name to :tickets for the whole controller
34 # * menu_item :tickets # => sets the menu name to :tickets for the whole controller
35 # * menu_item :tickets, :only => :list # => sets the menu name to :tickets for the 'list' action only
35 # * menu_item :tickets, :only => :list # => sets the menu name to :tickets for the 'list' action only
36 # * menu_item :tickets, :only => [:list, :show] # => sets the menu name to :tickets for 2 actions only
36 # * menu_item :tickets, :only => [:list, :show] # => sets the menu name to :tickets for 2 actions only
37 #
37 #
38 # The default menu item name for a controller is controller_name by default
38 # The default menu item name for a controller is controller_name by default
39 # Eg. the default menu item name for ProjectsController is :projects
39 # Eg. the default menu item name for ProjectsController is :projects
40 def menu_item(id, options = {})
40 def menu_item(id, options = {})
41 if actions = options[:only]
41 if actions = options[:only]
42 actions = [] << actions unless actions.is_a?(Array)
42 actions = [] << actions unless actions.is_a?(Array)
43 actions.each {|a| menu_items[controller_name.to_sym][:actions][a.to_sym] = id}
43 actions.each {|a| menu_items[controller_name.to_sym][:actions][a.to_sym] = id}
44 else
44 else
45 menu_items[controller_name.to_sym][:default] = id
45 menu_items[controller_name.to_sym][:default] = id
46 end
46 end
47 end
47 end
48 end
48 end
49
49
50 def menu_items
50 def menu_items
51 self.class.menu_items
51 self.class.menu_items
52 end
52 end
53
53
54 # Returns the menu item name according to the current action
54 # Returns the menu item name according to the current action
55 def current_menu_item
55 def current_menu_item
56 @current_menu_item ||= menu_items[controller_name.to_sym][:actions][action_name.to_sym] ||
56 @current_menu_item ||= menu_items[controller_name.to_sym][:actions][action_name.to_sym] ||
57 menu_items[controller_name.to_sym][:default]
57 menu_items[controller_name.to_sym][:default]
58 end
58 end
59
59
60 # Redirects user to the menu item of the given project
60 # Redirects user to the menu item of the given project
61 # Returns false if user is not authorized
61 # Returns false if user is not authorized
62 def redirect_to_project_menu_item(project, name)
62 def redirect_to_project_menu_item(project, name)
63 item = Redmine::MenuManager.items(:project_menu).detect {|i| i.name.to_s == name.to_s}
63 item = Redmine::MenuManager.items(:project_menu).detect {|i| i.name.to_s == name.to_s}
64 if item && User.current.allowed_to?(item.url, project) && (item.condition.nil? || item.condition.call(project))
64 if item && User.current.allowed_to?(item.url, project) && (item.condition.nil? || item.condition.call(project))
65 redirect_to({item.param => project}.merge(item.url))
65 redirect_to({item.param => project}.merge(item.url))
66 return true
66 return true
67 end
67 end
68 false
68 false
69 end
69 end
70 end
70 end
71
71
72 module MenuHelper
72 module MenuHelper
73 # Returns the current menu item name
73 # Returns the current menu item name
74 def current_menu_item
74 def current_menu_item
75 controller.current_menu_item
75 controller.current_menu_item
76 end
76 end
77
77
78 # Renders the application main menu
78 # Renders the application main menu
79 def render_main_menu(project)
79 def render_main_menu(project)
80 render_menu((project && !project.new_record?) ? :project_menu : :application_menu, project)
80 render_menu((project && !project.new_record?) ? :project_menu : :application_menu, project)
81 end
81 end
82
82
83 def display_main_menu?(project)
83 def display_main_menu?(project)
84 menu_name = project && !project.new_record? ? :project_menu : :application_menu
84 menu_name = project && !project.new_record? ? :project_menu : :application_menu
85 Redmine::MenuManager.items(menu_name).children.present?
85 Redmine::MenuManager.items(menu_name).children.present?
86 end
86 end
87
87
88 def render_menu(menu, project=nil)
88 def render_menu(menu, project=nil)
89 links = []
89 links = []
90 menu_items_for(menu, project) do |node|
90 menu_items_for(menu, project) do |node|
91 links << render_menu_node(node, project)
91 links << render_menu_node(node, project)
92 end
92 end
93 links.empty? ? nil : content_tag('ul', links.join("\n").html_safe)
93 links.empty? ? nil : content_tag('ul', links.join("\n").html_safe)
94 end
94 end
95
95
96 def render_menu_node(node, project=nil)
96 def render_menu_node(node, project=nil)
97 if node.children.present? || !node.child_menus.nil?
97 if node.children.present? || !node.child_menus.nil?
98 return render_menu_node_with_children(node, project)
98 return render_menu_node_with_children(node, project)
99 else
99 else
100 caption, url, selected = extract_node_details(node, project)
100 caption, url, selected = extract_node_details(node, project)
101 return content_tag('li',
101 return content_tag('li',
102 render_single_menu_node(node, caption, url, selected))
102 render_single_menu_node(node, caption, url, selected))
103 end
103 end
104 end
104 end
105
105
106 def render_menu_node_with_children(node, project=nil)
106 def render_menu_node_with_children(node, project=nil)
107 caption, url, selected = extract_node_details(node, project)
107 caption, url, selected = extract_node_details(node, project)
108
108
109 html = [].tap do |html|
109 html = [].tap do |html|
110 html << '<li>'
110 html << '<li>'
111 # Parent
111 # Parent
112 html << render_single_menu_node(node, caption, url, selected)
112 html << render_single_menu_node(node, caption, url, selected)
113
113
114 # Standard children
114 # Standard children
115 standard_children_list = "".tap do |child_html|
115 standard_children_list = "".html_safe.tap do |child_html|
116 node.children.each do |child|
116 node.children.each do |child|
117 child_html << render_menu_node(child, project)
117 child_html << render_menu_node(child, project)
118 end
118 end
119 end
119 end
120
120
121 html << content_tag(:ul, standard_children_list, :class => 'menu-children') unless standard_children_list.empty?
121 html << content_tag(:ul, standard_children_list, :class => 'menu-children') unless standard_children_list.empty?
122
122
123 # Unattached children
123 # Unattached children
124 unattached_children_list = render_unattached_children_menu(node, project)
124 unattached_children_list = render_unattached_children_menu(node, project)
125 html << content_tag(:ul, unattached_children_list, :class => 'menu-children unattached') unless unattached_children_list.blank?
125 html << content_tag(:ul, unattached_children_list, :class => 'menu-children unattached') unless unattached_children_list.blank?
126
126
127 html << '</li>'
127 html << '</li>'
128 end
128 end
129 return html.join("\n")
129 return html.join("\n").html_safe
130 end
130 end
131
131
132 # Returns a list of unattached children menu items
132 # Returns a list of unattached children menu items
133 def render_unattached_children_menu(node, project)
133 def render_unattached_children_menu(node, project)
134 return nil unless node.child_menus
134 return nil unless node.child_menus
135
135
136 "".tap do |child_html|
136 "".html_safe.tap do |child_html|
137 unattached_children = node.child_menus.call(project)
137 unattached_children = node.child_menus.call(project)
138 # Tree nodes support #each so we need to do object detection
138 # Tree nodes support #each so we need to do object detection
139 if unattached_children.is_a? Array
139 if unattached_children.is_a? Array
140 unattached_children.each do |child|
140 unattached_children.each do |child|
141 child_html << content_tag(:li, render_unattached_menu_item(child, project))
141 child_html << content_tag(:li, render_unattached_menu_item(child, project))
142 end
142 end
143 else
143 else
144 raise MenuError, ":child_menus must be an array of MenuItems"
144 raise MenuError, ":child_menus must be an array of MenuItems"
145 end
145 end
146 end
146 end
147 end
147 end
148
148
149 def render_single_menu_node(item, caption, url, selected)
149 def render_single_menu_node(item, caption, url, selected)
150 link_to(h(caption), url, item.html_options(:selected => selected))
150 link_to(h(caption), url, item.html_options(:selected => selected))
151 end
151 end
152
152
153 def render_unattached_menu_item(menu_item, project)
153 def render_unattached_menu_item(menu_item, project)
154 raise MenuError, ":child_menus must be an array of MenuItems" unless menu_item.is_a? MenuItem
154 raise MenuError, ":child_menus must be an array of MenuItems" unless menu_item.is_a? MenuItem
155
155
156 if User.current.allowed_to?(menu_item.url, project)
156 if User.current.allowed_to?(menu_item.url, project)
157 link_to(h(menu_item.caption),
157 link_to(h(menu_item.caption),
158 menu_item.url,
158 menu_item.url,
159 menu_item.html_options)
159 menu_item.html_options)
160 end
160 end
161 end
161 end
162
162
163 def menu_items_for(menu, project=nil)
163 def menu_items_for(menu, project=nil)
164 items = []
164 items = []
165 Redmine::MenuManager.items(menu).root.children.each do |node|
165 Redmine::MenuManager.items(menu).root.children.each do |node|
166 if allowed_node?(node, User.current, project)
166 if allowed_node?(node, User.current, project)
167 if block_given?
167 if block_given?
168 yield node
168 yield node
169 else
169 else
170 items << node # TODO: not used?
170 items << node # TODO: not used?
171 end
171 end
172 end
172 end
173 end
173 end
174 return block_given? ? nil : items
174 return block_given? ? nil : items
175 end
175 end
176
176
177 def extract_node_details(node, project=nil)
177 def extract_node_details(node, project=nil)
178 item = node
178 item = node
179 url = case item.url
179 url = case item.url
180 when Hash
180 when Hash
181 project.nil? ? item.url : {item.param => project}.merge(item.url)
181 project.nil? ? item.url : {item.param => project}.merge(item.url)
182 when Symbol
182 when Symbol
183 send(item.url)
183 send(item.url)
184 else
184 else
185 item.url
185 item.url
186 end
186 end
187 caption = item.caption(project)
187 caption = item.caption(project)
188 return [caption, url, (current_menu_item == item.name)]
188 return [caption, url, (current_menu_item == item.name)]
189 end
189 end
190
190
191 # Checks if a user is allowed to access the menu item by:
191 # Checks if a user is allowed to access the menu item by:
192 #
192 #
193 # * Checking the conditions of the item
193 # * Checking the conditions of the item
194 # * Checking the url target (project only)
194 # * Checking the url target (project only)
195 def allowed_node?(node, user, project)
195 def allowed_node?(node, user, project)
196 if node.condition && !node.condition.call(project)
196 if node.condition && !node.condition.call(project)
197 # Condition that doesn't pass
197 # Condition that doesn't pass
198 return false
198 return false
199 end
199 end
200
200
201 if project
201 if project
202 return user && user.allowed_to?(node.url, project)
202 return user && user.allowed_to?(node.url, project)
203 else
203 else
204 # outside a project, all menu items allowed
204 # outside a project, all menu items allowed
205 return true
205 return true
206 end
206 end
207 end
207 end
208 end
208 end
209
209
210 class << self
210 class << self
211 def map(menu_name)
211 def map(menu_name)
212 @items ||= {}
212 @items ||= {}
213 mapper = Mapper.new(menu_name.to_sym, @items)
213 mapper = Mapper.new(menu_name.to_sym, @items)
214 if block_given?
214 if block_given?
215 yield mapper
215 yield mapper
216 else
216 else
217 mapper
217 mapper
218 end
218 end
219 end
219 end
220
220
221 def items(menu_name)
221 def items(menu_name)
222 @items[menu_name.to_sym] || MenuNode.new(:root, {})
222 @items[menu_name.to_sym] || MenuNode.new(:root, {})
223 end
223 end
224 end
224 end
225
225
226 class Mapper
226 class Mapper
227 def initialize(menu, items)
227 def initialize(menu, items)
228 items[menu] ||= MenuNode.new(:root, {})
228 items[menu] ||= MenuNode.new(:root, {})
229 @menu = menu
229 @menu = menu
230 @menu_items = items[menu]
230 @menu_items = items[menu]
231 end
231 end
232
232
233 # Adds an item at the end of the menu. Available options:
233 # Adds an item at the end of the menu. Available options:
234 # * param: the parameter name that is used for the project id (default is :id)
234 # * param: the parameter name that is used for the project id (default is :id)
235 # * if: a Proc that is called before rendering the item, the item is displayed only if it returns true
235 # * if: a Proc that is called before rendering the item, the item is displayed only if it returns true
236 # * caption that can be:
236 # * caption that can be:
237 # * a localized string Symbol
237 # * a localized string Symbol
238 # * a String
238 # * a String
239 # * a Proc that can take the project as argument
239 # * a Proc that can take the project as argument
240 # * before, after: specify where the menu item should be inserted (eg. :after => :activity)
240 # * before, after: specify where the menu item should be inserted (eg. :after => :activity)
241 # * parent: menu item will be added as a child of another named menu (eg. :parent => :issues)
241 # * parent: menu item will be added as a child of another named menu (eg. :parent => :issues)
242 # * children: a Proc that is called before rendering the item. The Proc should return an array of MenuItems, which will be added as children to this item.
242 # * children: a Proc that is called before rendering the item. The Proc should return an array of MenuItems, which will be added as children to this item.
243 # eg. :children => Proc.new {|project| [Redmine::MenuManager::MenuItem.new(...)] }
243 # eg. :children => Proc.new {|project| [Redmine::MenuManager::MenuItem.new(...)] }
244 # * last: menu item will stay at the end (eg. :last => true)
244 # * last: menu item will stay at the end (eg. :last => true)
245 # * html_options: a hash of html options that are passed to link_to
245 # * html_options: a hash of html options that are passed to link_to
246 def push(name, url, options={})
246 def push(name, url, options={})
247 options = options.dup
247 options = options.dup
248
248
249 if options[:parent]
249 if options[:parent]
250 subtree = self.find(options[:parent])
250 subtree = self.find(options[:parent])
251 if subtree
251 if subtree
252 target_root = subtree
252 target_root = subtree
253 else
253 else
254 target_root = @menu_items.root
254 target_root = @menu_items.root
255 end
255 end
256
256
257 else
257 else
258 target_root = @menu_items.root
258 target_root = @menu_items.root
259 end
259 end
260
260
261 # menu item position
261 # menu item position
262 if first = options.delete(:first)
262 if first = options.delete(:first)
263 target_root.prepend(MenuItem.new(name, url, options))
263 target_root.prepend(MenuItem.new(name, url, options))
264 elsif before = options.delete(:before)
264 elsif before = options.delete(:before)
265
265
266 if exists?(before)
266 if exists?(before)
267 target_root.add_at(MenuItem.new(name, url, options), position_of(before))
267 target_root.add_at(MenuItem.new(name, url, options), position_of(before))
268 else
268 else
269 target_root.add(MenuItem.new(name, url, options))
269 target_root.add(MenuItem.new(name, url, options))
270 end
270 end
271
271
272 elsif after = options.delete(:after)
272 elsif after = options.delete(:after)
273
273
274 if exists?(after)
274 if exists?(after)
275 target_root.add_at(MenuItem.new(name, url, options), position_of(after) + 1)
275 target_root.add_at(MenuItem.new(name, url, options), position_of(after) + 1)
276 else
276 else
277 target_root.add(MenuItem.new(name, url, options))
277 target_root.add(MenuItem.new(name, url, options))
278 end
278 end
279
279
280 elsif options[:last] # don't delete, needs to be stored
280 elsif options[:last] # don't delete, needs to be stored
281 target_root.add_last(MenuItem.new(name, url, options))
281 target_root.add_last(MenuItem.new(name, url, options))
282 else
282 else
283 target_root.add(MenuItem.new(name, url, options))
283 target_root.add(MenuItem.new(name, url, options))
284 end
284 end
285 end
285 end
286
286
287 # Removes a menu item
287 # Removes a menu item
288 def delete(name)
288 def delete(name)
289 if found = self.find(name)
289 if found = self.find(name)
290 @menu_items.remove!(found)
290 @menu_items.remove!(found)
291 end
291 end
292 end
292 end
293
293
294 # Checks if a menu item exists
294 # Checks if a menu item exists
295 def exists?(name)
295 def exists?(name)
296 @menu_items.any? {|node| node.name == name}
296 @menu_items.any? {|node| node.name == name}
297 end
297 end
298
298
299 def find(name)
299 def find(name)
300 @menu_items.find {|node| node.name == name}
300 @menu_items.find {|node| node.name == name}
301 end
301 end
302
302
303 def position_of(name)
303 def position_of(name)
304 @menu_items.each do |node|
304 @menu_items.each do |node|
305 if node.name == name
305 if node.name == name
306 return node.position
306 return node.position
307 end
307 end
308 end
308 end
309 end
309 end
310 end
310 end
311
311
312 class MenuNode
312 class MenuNode
313 include Enumerable
313 include Enumerable
314 attr_accessor :parent
314 attr_accessor :parent
315 attr_reader :last_items_count, :name
315 attr_reader :last_items_count, :name
316
316
317 def initialize(name, content = nil)
317 def initialize(name, content = nil)
318 @name = name
318 @name = name
319 @children = []
319 @children = []
320 @last_items_count = 0
320 @last_items_count = 0
321 end
321 end
322
322
323 def children
323 def children
324 if block_given?
324 if block_given?
325 @children.each {|child| yield child}
325 @children.each {|child| yield child}
326 else
326 else
327 @children
327 @children
328 end
328 end
329 end
329 end
330
330
331 # Returns the number of descendants + 1
331 # Returns the number of descendants + 1
332 def size
332 def size
333 @children.inject(1) {|sum, node| sum + node.size}
333 @children.inject(1) {|sum, node| sum + node.size}
334 end
334 end
335
335
336 def each &block
336 def each &block
337 yield self
337 yield self
338 children { |child| child.each(&block) }
338 children { |child| child.each(&block) }
339 end
339 end
340
340
341 # Adds a child at first position
341 # Adds a child at first position
342 def prepend(child)
342 def prepend(child)
343 add_at(child, 0)
343 add_at(child, 0)
344 end
344 end
345
345
346 # Adds a child at given position
346 # Adds a child at given position
347 def add_at(child, position)
347 def add_at(child, position)
348 raise "Child already added" if find {|node| node.name == child.name}
348 raise "Child already added" if find {|node| node.name == child.name}
349
349
350 @children = @children.insert(position, child)
350 @children = @children.insert(position, child)
351 child.parent = self
351 child.parent = self
352 child
352 child
353 end
353 end
354
354
355 # Adds a child as last child
355 # Adds a child as last child
356 def add_last(child)
356 def add_last(child)
357 add_at(child, -1)
357 add_at(child, -1)
358 @last_items_count += 1
358 @last_items_count += 1
359 child
359 child
360 end
360 end
361
361
362 # Adds a child
362 # Adds a child
363 def add(child)
363 def add(child)
364 position = @children.size - @last_items_count
364 position = @children.size - @last_items_count
365 add_at(child, position)
365 add_at(child, position)
366 end
366 end
367 alias :<< :add
367 alias :<< :add
368
368
369 # Removes a child
369 # Removes a child
370 def remove!(child)
370 def remove!(child)
371 @children.delete(child)
371 @children.delete(child)
372 @last_items_count -= +1 if child && child.last
372 @last_items_count -= +1 if child && child.last
373 child.parent = nil
373 child.parent = nil
374 child
374 child
375 end
375 end
376
376
377 # Returns the position for this node in it's parent
377 # Returns the position for this node in it's parent
378 def position
378 def position
379 self.parent.children.index(self)
379 self.parent.children.index(self)
380 end
380 end
381
381
382 # Returns the root for this node
382 # Returns the root for this node
383 def root
383 def root
384 root = self
384 root = self
385 root = root.parent while root.parent
385 root = root.parent while root.parent
386 root
386 root
387 end
387 end
388 end
388 end
389
389
390 class MenuItem < MenuNode
390 class MenuItem < MenuNode
391 include Redmine::I18n
391 include Redmine::I18n
392 attr_reader :name, :url, :param, :condition, :parent, :child_menus, :last
392 attr_reader :name, :url, :param, :condition, :parent, :child_menus, :last
393
393
394 def initialize(name, url, options)
394 def initialize(name, url, options)
395 raise ArgumentError, "Invalid option :if for menu item '#{name}'" if options[:if] && !options[:if].respond_to?(:call)
395 raise ArgumentError, "Invalid option :if for menu item '#{name}'" if options[:if] && !options[:if].respond_to?(:call)
396 raise ArgumentError, "Invalid option :html for menu item '#{name}'" if options[:html] && !options[:html].is_a?(Hash)
396 raise ArgumentError, "Invalid option :html for menu item '#{name}'" if options[:html] && !options[:html].is_a?(Hash)
397 raise ArgumentError, "Cannot set the :parent to be the same as this item" if options[:parent] == name.to_sym
397 raise ArgumentError, "Cannot set the :parent to be the same as this item" if options[:parent] == name.to_sym
398 raise ArgumentError, "Invalid option :children for menu item '#{name}'" if options[:children] && !options[:children].respond_to?(:call)
398 raise ArgumentError, "Invalid option :children for menu item '#{name}'" if options[:children] && !options[:children].respond_to?(:call)
399 @name = name
399 @name = name
400 @url = url
400 @url = url
401 @condition = options[:if]
401 @condition = options[:if]
402 @param = options[:param] || :id
402 @param = options[:param] || :id
403 @caption = options[:caption]
403 @caption = options[:caption]
404 @html_options = options[:html] || {}
404 @html_options = options[:html] || {}
405 # Adds a unique class to each menu item based on its name
405 # Adds a unique class to each menu item based on its name
406 @html_options[:class] = [@html_options[:class], @name.to_s.dasherize].compact.join(' ')
406 @html_options[:class] = [@html_options[:class], @name.to_s.dasherize].compact.join(' ')
407 @parent = options[:parent]
407 @parent = options[:parent]
408 @child_menus = options[:children]
408 @child_menus = options[:children]
409 @last = options[:last] || false
409 @last = options[:last] || false
410 super @name.to_sym
410 super @name.to_sym
411 end
411 end
412
412
413 def caption(project=nil)
413 def caption(project=nil)
414 if @caption.is_a?(Proc)
414 if @caption.is_a?(Proc)
415 c = @caption.call(project).to_s
415 c = @caption.call(project).to_s
416 c = @name.to_s.humanize if c.blank?
416 c = @name.to_s.humanize if c.blank?
417 c
417 c
418 else
418 else
419 if @caption.nil?
419 if @caption.nil?
420 l_or_humanize(name, :prefix => 'label_')
420 l_or_humanize(name, :prefix => 'label_')
421 else
421 else
422 @caption.is_a?(Symbol) ? l(@caption) : @caption
422 @caption.is_a?(Symbol) ? l(@caption) : @caption
423 end
423 end
424 end
424 end
425 end
425 end
426
426
427 def html_options(options={})
427 def html_options(options={})
428 if options[:selected]
428 if options[:selected]
429 o = @html_options.dup
429 o = @html_options.dup
430 o[:class] += ' selected'
430 o[:class] += ' selected'
431 o
431 o
432 else
432 else
433 @html_options
433 @html_options
434 end
434 end
435 end
435 end
436 end
436 end
437 end
437 end
438 end
438 end
General Comments 0
You need to be logged in to leave comments. Login now