##// END OF EJS Templates
Prevent blank menu caption....
Jean-Philippe Lang -
r1648:937cee726905
parent child
Show More
@@ -1,178 +1,180
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 require 'gloc'
19 19
20 20 module Redmine
21 21 module MenuManager
22 22 module MenuController
23 23 def self.included(base)
24 24 base.extend(ClassMethods)
25 25 end
26 26
27 27 module ClassMethods
28 28 @@menu_items = Hash.new {|hash, key| hash[key] = {:default => key, :actions => {}}}
29 29 mattr_accessor :menu_items
30 30
31 31 # Set the menu item name for a controller or specific actions
32 32 # Examples:
33 33 # * menu_item :tickets # => sets the menu name to :tickets for the whole controller
34 34 # * menu_item :tickets, :only => :list # => sets the menu name to :tickets for the 'list' action only
35 35 # * menu_item :tickets, :only => [:list, :show] # => sets the menu name to :tickets for 2 actions only
36 36 #
37 37 # The default menu item name for a controller is controller_name by default
38 38 # Eg. the default menu item name for ProjectsController is :projects
39 39 def menu_item(id, options = {})
40 40 if actions = options[:only]
41 41 actions = [] << actions unless actions.is_a?(Array)
42 42 actions.each {|a| menu_items[controller_name.to_sym][:actions][a.to_sym] = id}
43 43 else
44 44 menu_items[controller_name.to_sym][:default] = id
45 45 end
46 46 end
47 47 end
48 48
49 49 def menu_items
50 50 self.class.menu_items
51 51 end
52 52
53 53 # Returns the menu item name according to the current action
54 54 def current_menu_item
55 55 menu_items[controller_name.to_sym][:actions][action_name.to_sym] ||
56 56 menu_items[controller_name.to_sym][:default]
57 57 end
58 58 end
59 59
60 60 module MenuHelper
61 61 # Returns the current menu item name
62 62 def current_menu_item
63 63 @controller.current_menu_item
64 64 end
65 65
66 66 # Renders the application main menu
67 67 def render_main_menu(project)
68 68 render_menu((project && !project.new_record?) ? :project_menu : :application_menu, project)
69 69 end
70 70
71 71 def render_menu(menu, project=nil)
72 72 links = []
73 73 Redmine::MenuManager.allowed_items(menu, User.current, project).each do |item|
74 74 unless item.condition && !item.condition.call(project)
75 75 url = case item.url
76 76 when Hash
77 77 project.nil? ? item.url : {item.param => project}.merge(item.url)
78 78 when Symbol
79 79 send(item.url)
80 80 else
81 81 item.url
82 82 end
83 83 caption = item.caption(project)
84 84 caption = l(caption) if caption.is_a?(Symbol)
85 85 links << content_tag('li',
86 86 link_to(h(caption), url, (current_menu_item == item.name ? item.html_options.merge(:class => 'selected') : item.html_options)))
87 87 end
88 88 end
89 89 links.empty? ? nil : content_tag('ul', links.join("\n"))
90 90 end
91 91 end
92 92
93 93 class << self
94 94 def map(menu_name)
95 95 @items ||= {}
96 96 mapper = Mapper.new(menu_name.to_sym, @items)
97 97 yield mapper
98 98 end
99 99
100 100 def items(menu_name)
101 101 @items[menu_name.to_sym] || []
102 102 end
103 103
104 104 def allowed_items(menu_name, user, project)
105 105 project ? items(menu_name).select {|item| user && user.allowed_to?(item.url, project)} : items(menu_name)
106 106 end
107 107 end
108 108
109 109 class Mapper
110 110 def initialize(menu, items)
111 111 items[menu] ||= []
112 112 @menu = menu
113 113 @menu_items = items[menu]
114 114 end
115 115
116 116 @@last_items_count = Hash.new {|h,k| h[k] = 0}
117 117
118 118 # Adds an item at the end of the menu. Available options:
119 119 # * param: the parameter name that is used for the project id (default is :id)
120 120 # * if: a Proc that is called before rendering the item, the item is displayed only if it returns true
121 121 # * caption that can be:
122 122 # * a localized string Symbol
123 123 # * a String
124 124 # * a Proc that can take the project as argument
125 125 # * before, after: specify where the menu item should be inserted (eg. :after => :activity)
126 126 # * last: menu item will stay at the end (eg. :last => true)
127 127 # * html_options: a hash of html options that are passed to link_to
128 128 def push(name, url, options={})
129 129 options = options.dup
130 130
131 131 # menu item position
132 132 if before = options.delete(:before)
133 133 position = @menu_items.index {|i| i.name == before}
134 134 elsif after = options.delete(:after)
135 135 position = @menu_items.index {|i| i.name == after}
136 136 position += 1 unless position.nil?
137 137 elsif options.delete(:last)
138 138 position = @menu_items.size
139 139 @@last_items_count[@menu] += 1
140 140 end
141 141 # default position
142 142 position ||= @menu_items.size - @@last_items_count[@menu]
143 143
144 144 @menu_items.insert(position, MenuItem.new(name, url, options))
145 145 end
146 146
147 147 # Removes a menu item
148 148 def delete(name)
149 149 @menu_items.delete_if {|i| i.name == name}
150 150 end
151 151 end
152 152
153 153 class MenuItem
154 154 include GLoc
155 155 attr_reader :name, :url, :param, :condition, :html_options
156 156
157 157 def initialize(name, url, options)
158 158 raise "Invalid option :if for menu item '#{name}'" if options[:if] && !options[:if].respond_to?(:call)
159 159 raise "Invalid option :html for menu item '#{name}'" if options[:html] && !options[:html].is_a?(Hash)
160 160 @name = name
161 161 @url = url
162 162 @condition = options[:if]
163 163 @param = options[:param] || :id
164 164 @caption = options[:caption]
165 165 @html_options = options[:html] || {}
166 166 end
167 167
168 168 def caption(project=nil)
169 169 if @caption.is_a?(Proc)
170 @caption.call(project)
170 c = @caption.call(project).to_s
171 c = @name.to_s.humanize if c.blank?
172 c
171 173 else
172 174 # check if localized string exists on first render (after GLoc strings are loaded)
173 175 @caption_key ||= (@caption || (l_has_string?("label_#{@name}".to_sym) ? "label_#{@name}".to_sym : @name.to_s.humanize))
174 176 end
175 177 end
176 178 end
177 179 end
178 180 end
General Comments 0
You need to be logged in to leave comments. Login now