##// END OF EJS Templates
Fixes #780: Redmine fails to start with a const_missing error on Redmine::MenuManager::MenuItem::GLoc (occurs when a Redmine plugin is loaded before GLoc)....
Jean-Philippe Lang -
r1173:d8c97b32dd3c
parent child
Show More
@@ -1,92 +1,92
1 # Be sure to restart your web server when you modify this file.
1 # Be sure to restart your web server when you modify this file.
2
2
3 # Uncomment below to force Rails into production mode when
3 # Uncomment below to force Rails into production mode when
4 # you don't control web/app server and can't set it the proper way
4 # you don't control web/app server and can't set it the proper way
5 # ENV['RAILS_ENV'] ||= 'production'
5 # ENV['RAILS_ENV'] ||= 'production'
6
6
7 # Bootstrap the Rails environment, frameworks, and default configuration
7 # Bootstrap the Rails environment, frameworks, and default configuration
8 require File.join(File.dirname(__FILE__), 'boot')
8 require File.join(File.dirname(__FILE__), 'boot')
9
9
10 Rails::Initializer.run do |config|
10 Rails::Initializer.run do |config|
11 # Settings in config/environments/* take precedence those specified here
11 # Settings in config/environments/* take precedence those specified here
12
12
13 # Skip frameworks you're not going to use
13 # Skip frameworks you're not going to use
14 # config.frameworks -= [ :action_web_service, :action_mailer ]
14 # config.frameworks -= [ :action_web_service, :action_mailer ]
15
15
16 # Add additional load paths for sweepers
16 # Add additional load paths for sweepers
17 config.load_paths += %W( #{RAILS_ROOT}/app/sweepers )
17 config.load_paths += %W( #{RAILS_ROOT}/app/sweepers )
18
18
19 # Force all environments to use the same logger level
19 # Force all environments to use the same logger level
20 # (by default production uses :info, the others :debug)
20 # (by default production uses :info, the others :debug)
21 # config.log_level = :debug
21 # config.log_level = :debug
22
22
23 # Use the database for sessions instead of the file system
23 # Use the database for sessions instead of the file system
24 # (create the session table with 'rake create_sessions_table')
24 # (create the session table with 'rake create_sessions_table')
25 # config.action_controller.session_store = :active_record_store
25 # config.action_controller.session_store = :active_record_store
26 config.action_controller.session_store = :PStore
26 config.action_controller.session_store = :PStore
27
27
28 # Enable page/fragment caching by setting a file-based store
28 # Enable page/fragment caching by setting a file-based store
29 # (remember to create the caching directory and make it readable to the application)
29 # (remember to create the caching directory and make it readable to the application)
30 # config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/cache"
30 # config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/cache"
31
31
32 # Activate observers that should always be running
32 # Activate observers that should always be running
33 # config.active_record.observers = :cacher, :garbage_collector
33 # config.active_record.observers = :cacher, :garbage_collector
34 config.active_record.observers = :message_observer
34 config.active_record.observers = :message_observer
35
35
36 # Make Active Record use UTC-base instead of local time
36 # Make Active Record use UTC-base instead of local time
37 # config.active_record.default_timezone = :utc
37 # config.active_record.default_timezone = :utc
38
38
39 # Use Active Record's schema dumper instead of SQL when creating the test database
39 # Use Active Record's schema dumper instead of SQL when creating the test database
40 # (enables use of different database adapters for development and test environments)
40 # (enables use of different database adapters for development and test environments)
41 # config.active_record.schema_format = :ruby
41 # config.active_record.schema_format = :ruby
42
42
43 # See Rails::Configuration for more options
43 # See Rails::Configuration for more options
44
44
45 # SMTP server configuration
45 # SMTP server configuration
46 config.action_mailer.smtp_settings = {
46 config.action_mailer.smtp_settings = {
47 :address => "127.0.0.1",
47 :address => "127.0.0.1",
48 :port => 25,
48 :port => 25,
49 :domain => "somenet.foo",
49 :domain => "somenet.foo",
50 :authentication => :login,
50 :authentication => :login,
51 :user_name => "redmine",
51 :user_name => "redmine@somenet.foo",
52 :password => "redmine",
52 :password => "redmine",
53 }
53 }
54
54
55 config.action_mailer.perform_deliveries = true
55 config.action_mailer.perform_deliveries = true
56
56
57 # Tell ActionMailer not to deliver emails to the real world.
57 # Tell ActionMailer not to deliver emails to the real world.
58 # The :test delivery method accumulates sent emails in the
58 # The :test delivery method accumulates sent emails in the
59 # ActionMailer::Base.deliveries array.
59 # ActionMailer::Base.deliveries array.
60 #config.action_mailer.delivery_method = :test
60 #config.action_mailer.delivery_method = :test
61 config.action_mailer.delivery_method = :smtp
61 config.action_mailer.delivery_method = :smtp
62
62
63 end
63 end
64
64
65 ActiveRecord::Errors.default_error_messages = {
65 ActiveRecord::Errors.default_error_messages = {
66 :inclusion => "activerecord_error_inclusion",
66 :inclusion => "activerecord_error_inclusion",
67 :exclusion => "activerecord_error_exclusion",
67 :exclusion => "activerecord_error_exclusion",
68 :invalid => "activerecord_error_invalid",
68 :invalid => "activerecord_error_invalid",
69 :confirmation => "activerecord_error_confirmation",
69 :confirmation => "activerecord_error_confirmation",
70 :accepted => "activerecord_error_accepted",
70 :accepted => "activerecord_error_accepted",
71 :empty => "activerecord_error_empty",
71 :empty => "activerecord_error_empty",
72 :blank => "activerecord_error_blank",
72 :blank => "activerecord_error_blank",
73 :too_long => "activerecord_error_too_long",
73 :too_long => "activerecord_error_too_long",
74 :too_short => "activerecord_error_too_short",
74 :too_short => "activerecord_error_too_short",
75 :wrong_length => "activerecord_error_wrong_length",
75 :wrong_length => "activerecord_error_wrong_length",
76 :taken => "activerecord_error_taken",
76 :taken => "activerecord_error_taken",
77 :not_a_number => "activerecord_error_not_a_number"
77 :not_a_number => "activerecord_error_not_a_number"
78 }
78 }
79
79
80 ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "#{html_tag}" }
80 ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "#{html_tag}" }
81
81
82 Mime::SET << Mime::CSV unless Mime::SET.include?(Mime::CSV)
82 Mime::SET << Mime::CSV unless Mime::SET.include?(Mime::CSV)
83 Mime::Type.register 'application/pdf', :pdf
83 Mime::Type.register 'application/pdf', :pdf
84
84
85 GLoc.set_config :default_language => :en
85 GLoc.set_config :default_language => :en
86 GLoc.clear_strings
86 GLoc.clear_strings
87 GLoc.set_kcode
87 GLoc.set_kcode
88 GLoc.load_localized_strings
88 GLoc.load_localized_strings
89 GLoc.set_config(:raise_string_not_found_errors => false)
89 GLoc.set_config(:raise_string_not_found_errors => false)
90
90
91 require 'redmine'
91 require 'redmine'
92
92
@@ -1,144 +1,146
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 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 require 'gloc'
19
18 module Redmine
20 module Redmine
19 module MenuManager
21 module MenuManager
20 module MenuController
22 module MenuController
21 def self.included(base)
23 def self.included(base)
22 base.extend(ClassMethods)
24 base.extend(ClassMethods)
23 end
25 end
24
26
25 module ClassMethods
27 module ClassMethods
26 @@menu_items = Hash.new {|hash, key| hash[key] = {:default => key, :actions => {}}}
28 @@menu_items = Hash.new {|hash, key| hash[key] = {:default => key, :actions => {}}}
27 mattr_accessor :menu_items
29 mattr_accessor :menu_items
28
30
29 # Set the menu item name for a controller or specific actions
31 # Set the menu item name for a controller or specific actions
30 # Examples:
32 # Examples:
31 # * menu_item :tickets # => sets the menu name to :tickets for the whole controller
33 # * menu_item :tickets # => sets the menu name to :tickets for the whole controller
32 # * menu_item :tickets, :only => :list # => sets the menu name to :tickets for the 'list' action only
34 # * menu_item :tickets, :only => :list # => sets the menu name to :tickets for the 'list' action only
33 # * menu_item :tickets, :only => [:list, :show] # => sets the menu name to :tickets for 2 actions only
35 # * menu_item :tickets, :only => [:list, :show] # => sets the menu name to :tickets for 2 actions only
34 #
36 #
35 # The default menu item name for a controller is controller_name by default
37 # The default menu item name for a controller is controller_name by default
36 # Eg. the default menu item name for ProjectsController is :projects
38 # Eg. the default menu item name for ProjectsController is :projects
37 def menu_item(id, options = {})
39 def menu_item(id, options = {})
38 if actions = options[:only]
40 if actions = options[:only]
39 actions = [] << actions unless actions.is_a?(Array)
41 actions = [] << actions unless actions.is_a?(Array)
40 actions.each {|a| menu_items[controller_name.to_sym][:actions][a.to_sym] = id}
42 actions.each {|a| menu_items[controller_name.to_sym][:actions][a.to_sym] = id}
41 else
43 else
42 menu_items[controller_name.to_sym][:default] = id
44 menu_items[controller_name.to_sym][:default] = id
43 end
45 end
44 end
46 end
45 end
47 end
46
48
47 def menu_items
49 def menu_items
48 self.class.menu_items
50 self.class.menu_items
49 end
51 end
50
52
51 # Returns the menu item name according to the current action
53 # Returns the menu item name according to the current action
52 def current_menu_item
54 def current_menu_item
53 menu_items[controller_name.to_sym][:actions][action_name.to_sym] ||
55 menu_items[controller_name.to_sym][:actions][action_name.to_sym] ||
54 menu_items[controller_name.to_sym][:default]
56 menu_items[controller_name.to_sym][:default]
55 end
57 end
56 end
58 end
57
59
58 module MenuHelper
60 module MenuHelper
59 # Returns the current menu item name
61 # Returns the current menu item name
60 def current_menu_item
62 def current_menu_item
61 @controller.current_menu_item
63 @controller.current_menu_item
62 end
64 end
63
65
64 # Renders the application main menu
66 # Renders the application main menu
65 def render_main_menu(project)
67 def render_main_menu(project)
66 render_menu((project && !project.new_record?) ? :project_menu : :application_menu, project)
68 render_menu((project && !project.new_record?) ? :project_menu : :application_menu, project)
67 end
69 end
68
70
69 def render_menu(menu, project=nil)
71 def render_menu(menu, project=nil)
70 links = []
72 links = []
71 Redmine::MenuManager.allowed_items(menu, User.current, project).each do |item|
73 Redmine::MenuManager.allowed_items(menu, User.current, project).each do |item|
72 unless item.condition && !item.condition.call(project)
74 unless item.condition && !item.condition.call(project)
73 url = case item.url
75 url = case item.url
74 when Hash
76 when Hash
75 project.nil? ? item.url : {item.param => project}.merge(item.url)
77 project.nil? ? item.url : {item.param => project}.merge(item.url)
76 when Symbol
78 when Symbol
77 send(item.url)
79 send(item.url)
78 else
80 else
79 item.url
81 item.url
80 end
82 end
81 #url = (project && item.url.is_a?(Hash)) ? {item.param => project}.merge(item.url) : (item.url.is_a?(Symbol) ? send(item.url) : item.url)
83 #url = (project && item.url.is_a?(Hash)) ? {item.param => project}.merge(item.url) : (item.url.is_a?(Symbol) ? send(item.url) : item.url)
82 links << content_tag('li',
84 links << content_tag('li',
83 link_to(l(item.caption), url, (current_menu_item == item.name ? item.html_options.merge(:class => 'selected') : item.html_options)))
85 link_to(l(item.caption), url, (current_menu_item == item.name ? item.html_options.merge(:class => 'selected') : item.html_options)))
84 end
86 end
85 end
87 end
86 links.empty? ? nil : content_tag('ul', links.join("\n"))
88 links.empty? ? nil : content_tag('ul', links.join("\n"))
87 end
89 end
88 end
90 end
89
91
90 class << self
92 class << self
91 def map(menu_name)
93 def map(menu_name)
92 mapper = Mapper.new
94 mapper = Mapper.new
93 yield mapper
95 yield mapper
94 @items ||= {}
96 @items ||= {}
95 @items[menu_name.to_sym] ||= []
97 @items[menu_name.to_sym] ||= []
96 @items[menu_name.to_sym] += mapper.items
98 @items[menu_name.to_sym] += mapper.items
97 end
99 end
98
100
99 def items(menu_name)
101 def items(menu_name)
100 @items[menu_name.to_sym] || []
102 @items[menu_name.to_sym] || []
101 end
103 end
102
104
103 def allowed_items(menu_name, user, project)
105 def allowed_items(menu_name, user, project)
104 project ? items(menu_name).select {|item| user && user.allowed_to?(item.url, project)} : items(menu_name)
106 project ? items(menu_name).select {|item| user && user.allowed_to?(item.url, project)} : items(menu_name)
105 end
107 end
106 end
108 end
107
109
108 class Mapper
110 class Mapper
109 # Adds an item at the end of the menu. Available options:
111 # Adds an item at the end of the menu. Available options:
110 # * param: the parameter name that is used for the project id (default is :id)
112 # * param: the parameter name that is used for the project id (default is :id)
111 # * if: a proc that is called before rendering the item, the item is displayed only if it returns true
113 # * if: a proc that is called before rendering the item, the item is displayed only if it returns true
112 # * caption: the localized string key that is used as the item label
114 # * caption: the localized string key that is used as the item label
113 # * html_options: a hash of html options that are passed to link_to
115 # * html_options: a hash of html options that are passed to link_to
114 def push(name, url, options={})
116 def push(name, url, options={})
115 items << MenuItem.new(name, url, options)
117 items << MenuItem.new(name, url, options)
116 end
118 end
117
119
118 def items
120 def items
119 @items ||= []
121 @items ||= []
120 end
122 end
121 end
123 end
122
124
123 class MenuItem
125 class MenuItem
124 include GLoc
126 include GLoc
125 attr_reader :name, :url, :param, :condition, :html_options
127 attr_reader :name, :url, :param, :condition, :html_options
126
128
127 def initialize(name, url, options)
129 def initialize(name, url, options)
128 raise "Invalid option :if for menu item '#{name}'" if options[:if] && !options[:if].respond_to?(:call)
130 raise "Invalid option :if for menu item '#{name}'" if options[:if] && !options[:if].respond_to?(:call)
129 raise "Invalid option :html for menu item '#{name}'" if options[:html] && !options[:html].is_a?(Hash)
131 raise "Invalid option :html for menu item '#{name}'" if options[:html] && !options[:html].is_a?(Hash)
130 @name = name
132 @name = name
131 @url = url
133 @url = url
132 @condition = options[:if]
134 @condition = options[:if]
133 @param = options[:param] || :id
135 @param = options[:param] || :id
134 @caption_key = options[:caption]
136 @caption_key = options[:caption]
135 @html_options = options[:html] || {}
137 @html_options = options[:html] || {}
136 end
138 end
137
139
138 def caption
140 def caption
139 # check if localized string exists on first render (after GLoc strings are loaded)
141 # check if localized string exists on first render (after GLoc strings are loaded)
140 @caption ||= (@caption_key || (l_has_string?("label_#{@name}".to_sym) ? "label_#{@name}".to_sym : @name.to_s.humanize))
142 @caption ||= (@caption_key || (l_has_string?("label_#{@name}".to_sym) ? "label_#{@name}".to_sym : @name.to_s.humanize))
141 end
143 end
142 end
144 end
143 end
145 end
144 end
146 end
General Comments 0
You need to be logged in to leave comments. Login now