##// END OF EJS Templates
Workaround for i18n 0.4.x with the old style syntax. #6428 #5608...
Eric Davis -
r4069:768d67f27bf6
parent child
Show More
@@ -1,80 +1,94
1
1
2 require 'active_record'
2 require 'active_record'
3
3
4 module ActiveRecord
4 module ActiveRecord
5 class Base
5 class Base
6 include Redmine::I18n
6 include Redmine::I18n
7
7
8 # Translate attribute names for validation errors display
8 # Translate attribute names for validation errors display
9 def self.human_attribute_name(attr)
9 def self.human_attribute_name(attr)
10 l("field_#{attr.to_s.gsub(/_id$/, '')}")
10 l("field_#{attr.to_s.gsub(/_id$/, '')}")
11 end
11 end
12 end
12 end
13 end
13 end
14
14
15 module ActiveRecord
15 module ActiveRecord
16 class Errors
16 class Errors
17 def full_messages(options = {})
17 def full_messages(options = {})
18 full_messages = []
18 full_messages = []
19
19
20 @errors.each_key do |attr|
20 @errors.each_key do |attr|
21 @errors[attr].each do |message|
21 @errors[attr].each do |message|
22 next unless message
22 next unless message
23
23
24 if attr == "base"
24 if attr == "base"
25 full_messages << message
25 full_messages << message
26 elsif attr == "custom_values"
26 elsif attr == "custom_values"
27 # Replace the generic "custom values is invalid"
27 # Replace the generic "custom values is invalid"
28 # with the errors on custom values
28 # with the errors on custom values
29 @base.custom_values.each do |value|
29 @base.custom_values.each do |value|
30 value.errors.each do |attr, msg|
30 value.errors.each do |attr, msg|
31 full_messages << value.custom_field.name + ' ' + msg
31 full_messages << value.custom_field.name + ' ' + msg
32 end
32 end
33 end
33 end
34 else
34 else
35 attr_name = @base.class.human_attribute_name(attr)
35 attr_name = @base.class.human_attribute_name(attr)
36 full_messages << attr_name + ' ' + message.to_s
36 full_messages << attr_name + ' ' + message.to_s
37 end
37 end
38 end
38 end
39 end
39 end
40 full_messages
40 full_messages
41 end
41 end
42 end
42 end
43 end
43 end
44
44
45 module ActionView
45 module ActionView
46 module Helpers
46 module Helpers
47 module DateHelper
47 module DateHelper
48 # distance_of_time_in_words breaks when difference is greater than 30 years
48 # distance_of_time_in_words breaks when difference is greater than 30 years
49 def distance_of_date_in_words(from_date, to_date = 0, options = {})
49 def distance_of_date_in_words(from_date, to_date = 0, options = {})
50 from_date = from_date.to_date if from_date.respond_to?(:to_date)
50 from_date = from_date.to_date if from_date.respond_to?(:to_date)
51 to_date = to_date.to_date if to_date.respond_to?(:to_date)
51 to_date = to_date.to_date if to_date.respond_to?(:to_date)
52 distance_in_days = (to_date - from_date).abs
52 distance_in_days = (to_date - from_date).abs
53
53
54 I18n.with_options :locale => options[:locale], :scope => :'datetime.distance_in_words' do |locale|
54 I18n.with_options :locale => options[:locale], :scope => :'datetime.distance_in_words' do |locale|
55 case distance_in_days
55 case distance_in_days
56 when 0..60 then locale.t :x_days, :count => distance_in_days.round
56 when 0..60 then locale.t :x_days, :count => distance_in_days.round
57 when 61..720 then locale.t :about_x_months, :count => (distance_in_days / 30).round
57 when 61..720 then locale.t :about_x_months, :count => (distance_in_days / 30).round
58 else locale.t :over_x_years, :count => (distance_in_days / 365).floor
58 else locale.t :over_x_years, :count => (distance_in_days / 365).floor
59 end
59 end
60 end
60 end
61 end
61 end
62 end
62 end
63 end
63 end
64 end
64 end
65
65
66 ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "#{html_tag}" }
66 ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "#{html_tag}" }
67
67
68 # Adds :async_smtp and :async_sendmail delivery methods
68 # Adds :async_smtp and :async_sendmail delivery methods
69 # to perform email deliveries asynchronously
69 # to perform email deliveries asynchronously
70 module AsynchronousMailer
70 module AsynchronousMailer
71 %w(smtp sendmail).each do |type|
71 %w(smtp sendmail).each do |type|
72 define_method("perform_delivery_async_#{type}") do |mail|
72 define_method("perform_delivery_async_#{type}") do |mail|
73 Thread.start do
73 Thread.start do
74 send "perform_delivery_#{type}", mail
74 send "perform_delivery_#{type}", mail
75 end
75 end
76 end
76 end
77 end
77 end
78 end
78 end
79
79
80 ActionMailer::Base.send :include, AsynchronousMailer
80 ActionMailer::Base.send :include, AsynchronousMailer
81
82 # TODO: Hack to support i18n 4.x on Rails 2.3.5. Remove post 2.3.6.
83 # See http://www.redmine.org/issues/6428 and http://www.redmine.org/issues/5608
84 module I18n
85 module Backend
86 module Base
87 def warn_syntax_deprecation!
88 return if @skip_syntax_deprecation
89 warn "The {{key}} interpolation syntax in I18n messages is deprecated. Please use %{key} instead.\nDowngrade your i18n gem to 0.3.7 (everything above must be deinstalled) to remove this warning, see http://www.redmine.org/issues/5608 for more information."
90 @skip_syntax_deprecation = true
91 end
92 end
93 end
94 end
@@ -1,79 +1,79
1 module Redmine
1 module Redmine
2 module I18n
2 module I18n
3 def self.included(base)
3 def self.included(base)
4 base.extend Redmine::I18n
4 base.extend Redmine::I18n
5 end
5 end
6
6
7 def l(*args)
7 def l(*args)
8 case args.size
8 case args.size
9 when 1
9 when 1
10 ::I18n.t(*args)
10 ::I18n.t(*args)
11 when 2
11 when 2
12 if args.last.is_a?(Hash)
12 if args.last.is_a?(Hash)
13 ::I18n.t(*args)
13 ::I18n.t(*args)
14 elsif args.last.is_a?(String)
14 elsif args.last.is_a?(String)
15 ::I18n.t(args.first, :value => args.last)
15 ::I18n.t(args.first, :value => args.last)
16 else
16 else
17 ::I18n.t(args.first, :count => args.last)
17 ::I18n.t(args.first, :count => args.last)
18 end
18 end
19 else
19 else
20 raise "Translation string with multiple values: #{args.first}"
20 raise "Translation string with multiple values: #{args.first}"
21 end
21 end
22 end
22 end
23
23
24 def l_or_humanize(s, options={})
24 def l_or_humanize(s, options={})
25 k = "#{options[:prefix]}#{s}".to_sym
25 k = "#{options[:prefix]}#{s}".to_sym
26 ::I18n.t(k, :default => s.to_s.humanize)
26 ::I18n.t(k, :default => s.to_s.humanize)
27 end
27 end
28
28
29 def l_hours(hours)
29 def l_hours(hours)
30 hours = hours.to_f
30 hours = hours.to_f
31 l((hours < 2.0 ? :label_f_hour : :label_f_hour_plural), :value => ("%.2f" % hours.to_f))
31 l((hours < 2.0 ? :label_f_hour : :label_f_hour_plural), :value => ("%.2f" % hours.to_f))
32 end
32 end
33
33
34 def ll(lang, str, value=nil)
34 def ll(lang, str, value=nil)
35 ::I18n.t(str.to_s, :value => value, :locale => lang.to_s.gsub(%r{(.+)\-(.+)$}) { "#{$1}-#{$2.upcase}" })
35 ::I18n.t(str.to_s, :value => value, :locale => lang.to_s.gsub(%r{(.+)\-(.+)$}) { "#{$1}-#{$2.upcase}" })
36 end
36 end
37
37
38 def format_date(date)
38 def format_date(date)
39 return nil unless date
39 return nil unless date
40 Setting.date_format.blank? ? ::I18n.l(date.to_date) : date.strftime(Setting.date_format)
40 Setting.date_format.blank? ? ::I18n.l(date.to_date, :count => date.strftime('%d')) : date.strftime(Setting.date_format)
41 end
41 end
42
42
43 def format_time(time, include_date = true)
43 def format_time(time, include_date = true)
44 return nil unless time
44 return nil unless time
45 time = time.to_time if time.is_a?(String)
45 time = time.to_time if time.is_a?(String)
46 zone = User.current.time_zone
46 zone = User.current.time_zone
47 local = zone ? time.in_time_zone(zone) : (time.utc? ? time.localtime : time)
47 local = zone ? time.in_time_zone(zone) : (time.utc? ? time.localtime : time)
48 Setting.time_format.blank? ? ::I18n.l(local, :format => (include_date ? :default : :time)) :
48 Setting.time_format.blank? ? ::I18n.l(local, :count => local.strftime('%d'), :format => (include_date ? :default : :time)) :
49 ((include_date ? "#{format_date(time)} " : "") + "#{local.strftime(Setting.time_format)}")
49 ((include_date ? "#{format_date(time)} " : "") + "#{local.strftime(Setting.time_format)}")
50 end
50 end
51
51
52 def day_name(day)
52 def day_name(day)
53 ::I18n.t('date.day_names')[day % 7]
53 ::I18n.t('date.day_names')[day % 7]
54 end
54 end
55
55
56 def month_name(month)
56 def month_name(month)
57 ::I18n.t('date.month_names')[month]
57 ::I18n.t('date.month_names')[month]
58 end
58 end
59
59
60 def valid_languages
60 def valid_languages
61 @@valid_languages ||= Dir.glob(File.join(RAILS_ROOT, 'config', 'locales', '*.yml')).collect {|f| File.basename(f).split('.').first}.collect(&:to_sym)
61 @@valid_languages ||= Dir.glob(File.join(RAILS_ROOT, 'config', 'locales', '*.yml')).collect {|f| File.basename(f).split('.').first}.collect(&:to_sym)
62 end
62 end
63
63
64 def find_language(lang)
64 def find_language(lang)
65 @@languages_lookup = valid_languages.inject({}) {|k, v| k[v.to_s.downcase] = v; k }
65 @@languages_lookup = valid_languages.inject({}) {|k, v| k[v.to_s.downcase] = v; k }
66 @@languages_lookup[lang.to_s.downcase]
66 @@languages_lookup[lang.to_s.downcase]
67 end
67 end
68
68
69 def set_language_if_valid(lang)
69 def set_language_if_valid(lang)
70 if l = find_language(lang)
70 if l = find_language(lang)
71 ::I18n.locale = l
71 ::I18n.locale = l
72 end
72 end
73 end
73 end
74
74
75 def current_language
75 def current_language
76 ::I18n.locale
76 ::I18n.locale
77 end
77 end
78 end
78 end
79 end
79 end
@@ -1,112 +1,112
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2009 Jean-Philippe Lang
2 # Copyright (C) 2006-2009 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 File.dirname(__FILE__) + '/../../../test_helper'
18 require File.dirname(__FILE__) + '/../../../test_helper'
19
19
20 class Redmine::I18nTest < ActiveSupport::TestCase
20 class Redmine::I18nTest < ActiveSupport::TestCase
21 include Redmine::I18n
21 include Redmine::I18n
22 include ActionView::Helpers::NumberHelper
22 include ActionView::Helpers::NumberHelper
23
23
24 def setup
24 def setup
25 @hook_module = Redmine::Hook
25 @hook_module = Redmine::Hook
26 end
26 end
27
27
28 def test_date_format_default
28 def test_date_format_default
29 set_language_if_valid 'en'
29 set_language_if_valid 'en'
30 today = Date.today
30 today = Date.today
31 Setting.date_format = ''
31 Setting.date_format = ''
32 assert_equal I18n.l(today), format_date(today)
32 assert_equal I18n.l(today, :count => today.strftime('%d')), format_date(today)
33 end
33 end
34
34
35 def test_date_format
35 def test_date_format
36 set_language_if_valid 'en'
36 set_language_if_valid 'en'
37 today = Date.today
37 today = Date.today
38 Setting.date_format = '%d %m %Y'
38 Setting.date_format = '%d %m %Y'
39 assert_equal today.strftime('%d %m %Y'), format_date(today)
39 assert_equal today.strftime('%d %m %Y'), format_date(today)
40 end
40 end
41
41
42 def test_date_and_time_for_each_language
42 def test_date_and_time_for_each_language
43 Setting.date_format = ''
43 Setting.date_format = ''
44 valid_languages.each do |lang|
44 valid_languages.each do |lang|
45 set_language_if_valid lang
45 set_language_if_valid lang
46 assert_nothing_raised "#{lang} failure" do
46 assert_nothing_raised "#{lang} failure" do
47 format_date(Date.today)
47 format_date(Date.today)
48 format_time(Time.now)
48 format_time(Time.now)
49 format_time(Time.now, false)
49 format_time(Time.now, false)
50 assert_not_equal 'default', ::I18n.l(Date.today, :format => :default), "date.formats.default missing in #{lang}"
50 assert_not_equal 'default', ::I18n.l(Date.today, :count => Date.today.strftime('%d'), :format => :default), "date.formats.default missing in #{lang}"
51 assert_not_equal 'time', ::I18n.l(Time.now, :format => :time), "time.formats.time missing in #{lang}"
51 assert_not_equal 'time', ::I18n.l(Time.now, :format => :time), "time.formats.time missing in #{lang}"
52 end
52 end
53 assert l('date.day_names').is_a?(Array)
53 assert l('date.day_names').is_a?(Array)
54 assert_equal 7, l('date.day_names').size
54 assert_equal 7, l('date.day_names').size
55
55
56 assert l('date.month_names').is_a?(Array)
56 assert l('date.month_names').is_a?(Array)
57 assert_equal 13, l('date.month_names').size
57 assert_equal 13, l('date.month_names').size
58 end
58 end
59 end
59 end
60
60
61 def test_time_format_default
61 def test_time_format_default
62 set_language_if_valid 'en'
62 set_language_if_valid 'en'
63 now = Time.now
63 now = Time.now
64 Setting.date_format = ''
64 Setting.date_format = ''
65 Setting.time_format = ''
65 Setting.time_format = ''
66 assert_equal I18n.l(now), format_time(now)
66 assert_equal I18n.l(now, :count => now.strftime('%d')), format_time(now)
67 assert_equal I18n.l(now, :format => :time), format_time(now, false)
67 assert_equal I18n.l(now, :count => now.strftime('%d'), :format => :time), format_time(now, false)
68 end
68 end
69
69
70 def test_time_format
70 def test_time_format
71 set_language_if_valid 'en'
71 set_language_if_valid 'en'
72 now = Time.now
72 now = Time.now
73 Setting.date_format = '%d %m %Y'
73 Setting.date_format = '%d %m %Y'
74 Setting.time_format = '%H %M'
74 Setting.time_format = '%H %M'
75 assert_equal now.strftime('%d %m %Y %H %M'), format_time(now)
75 assert_equal now.strftime('%d %m %Y %H %M'), format_time(now)
76 assert_equal now.strftime('%H %M'), format_time(now, false)
76 assert_equal now.strftime('%H %M'), format_time(now, false)
77 end
77 end
78
78
79 def test_utc_time_format
79 def test_utc_time_format
80 set_language_if_valid 'en'
80 set_language_if_valid 'en'
81 now = Time.now.utc
81 now = Time.now.utc
82 Setting.date_format = '%d %m %Y'
82 Setting.date_format = '%d %m %Y'
83 Setting.time_format = '%H %M'
83 Setting.time_format = '%H %M'
84 assert_equal Time.now.strftime('%d %m %Y %H %M'), format_time(now)
84 assert_equal Time.now.strftime('%d %m %Y %H %M'), format_time(now)
85 assert_equal Time.now.strftime('%H %M'), format_time(now, false)
85 assert_equal Time.now.strftime('%H %M'), format_time(now, false)
86 end
86 end
87
87
88 def test_number_to_human_size_for_each_language
88 def test_number_to_human_size_for_each_language
89 valid_languages.each do |lang|
89 valid_languages.each do |lang|
90 set_language_if_valid lang
90 set_language_if_valid lang
91 assert_nothing_raised "#{lang} failure" do
91 assert_nothing_raised "#{lang} failure" do
92 number_to_human_size(1024*1024*4)
92 number_to_human_size(1024*1024*4)
93 end
93 end
94 end
94 end
95 end
95 end
96
96
97 def test_valid_languages
97 def test_valid_languages
98 assert valid_languages.is_a?(Array)
98 assert valid_languages.is_a?(Array)
99 assert valid_languages.first.is_a?(Symbol)
99 assert valid_languages.first.is_a?(Symbol)
100 end
100 end
101
101
102 def test_valid_language
102 def test_valid_language
103 to_test = {'fr' => :fr,
103 to_test = {'fr' => :fr,
104 'Fr' => :fr,
104 'Fr' => :fr,
105 'zh' => :zh,
105 'zh' => :zh,
106 'zh-tw' => :"zh-TW",
106 'zh-tw' => :"zh-TW",
107 'zh-TW' => :"zh-TW",
107 'zh-TW' => :"zh-TW",
108 'zh-ZZ' => nil }
108 'zh-ZZ' => nil }
109
109
110 to_test.each {|lang, expected| assert_equal expected, find_language(lang)}
110 to_test.each {|lang, expected| assert_equal expected, find_language(lang)}
111 end
111 end
112 end
112 end
General Comments 0
You need to be logged in to leave comments. Login now