russian 0.2.7 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/CHANGELOG +24 -0
  2. data/Gemfile +9 -0
  3. data/LICENSE +1 -1
  4. data/README.textile +136 -139
  5. data/Rakefile +4 -49
  6. data/TODO +0 -6
  7. data/lib/russian.rb +18 -39
  8. data/lib/russian/action_view_ext/helpers/date_helper.rb +15 -9
  9. data/lib/russian/active_model_ext/custom_error_message.rb +70 -0
  10. data/lib/russian/locale/actionview.yml +100 -50
  11. data/lib/russian/locale/activemodel.yml +50 -0
  12. data/lib/russian/locale/activerecord.yml +24 -24
  13. data/lib/russian/locale/datetime.rb +39 -0
  14. data/lib/russian/locale/datetime.yml +9 -5
  15. data/lib/russian/locale/pluralization.rb +28 -0
  16. data/lib/russian/locale/transliterator.rb +17 -0
  17. data/lib/russian/russian_rails.rb +8 -0
  18. data/lib/russian/version.rb +9 -0
  19. data/russian.gemspec +26 -0
  20. data/spec/locale_spec.rb +5 -87
  21. data/spec/russian_spec.rb +5 -23
  22. metadata +70 -69
  23. data/init.rb +0 -3
  24. data/lib/russian/active_record_ext/custom_error_message.rb +0 -163
  25. data/lib/russian/active_support_ext/parameterize.rb +0 -31
  26. data/lib/russian/backend/advanced.rb +0 -134
  27. data/lib/russian/locale/pluralize.rb +0 -25
  28. data/lib/vendor/i18n/MIT-LICENSE +0 -20
  29. data/lib/vendor/i18n/README.textile +0 -20
  30. data/lib/vendor/i18n/Rakefile +0 -5
  31. data/lib/vendor/i18n/i18n.gemspec +0 -27
  32. data/lib/vendor/i18n/lib/i18n.rb +0 -199
  33. data/lib/vendor/i18n/lib/i18n/backend/simple.rb +0 -214
  34. data/lib/vendor/i18n/lib/i18n/exceptions.rb +0 -53
  35. data/lib/vendor/i18n/test/all.rb +0 -5
  36. data/lib/vendor/i18n/test/i18n_exceptions_test.rb +0 -100
  37. data/lib/vendor/i18n/test/i18n_test.rb +0 -125
  38. data/lib/vendor/i18n/test/locale/en.rb +0 -1
  39. data/lib/vendor/i18n/test/locale/en.yml +0 -3
  40. data/lib/vendor/i18n/test/simple_backend_test.rb +0 -568
  41. data/lib/vendor/i18n_label/README.textile +0 -38
  42. data/lib/vendor/i18n_label/Rakefile +0 -11
  43. data/lib/vendor/i18n_label/init.rb +0 -1
  44. data/lib/vendor/i18n_label/install.rb +0 -1
  45. data/lib/vendor/i18n_label/lib/i18n_label.rb +0 -23
  46. data/lib/vendor/i18n_label/spec/i18n_label_spec.rb +0 -20
  47. data/lib/vendor/i18n_label/spec/spec_helper.rb +0 -10
  48. data/lib/vendor/i18n_label/tasks/i18n_label_tasks.rake +0 -4
  49. data/lib/vendor/i18n_label/uninstall.rb +0 -1
data/TODO CHANGED
@@ -1,10 +1,4 @@
1
1
  TODO
2
2
  ====
3
3
  * RDoc
4
- * check Unicode CLDR to ensure all datetime formats are correct
5
- * refactor Advanced backend localize method (looks ugly)
6
- * refactor DateTimeSelector#translated_month_names
7
4
 
8
- Questionable
9
- ============
10
- * integration specs for rails hacks
@@ -1,38 +1,16 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
- if RUBY_VERSION < "1.9"
4
- $KCODE = 'u'
5
- end
6
-
7
- $:.push File.join(File.dirname(__FILE__), 'russian')
8
- require 'transliteration'
3
+ $KCODE = 'u' if RUBY_VERSION < "1.9"
9
4
 
10
- # I18n require
11
- unless defined?(I18n)
12
- $:.push File.join(File.dirname(__FILE__), 'vendor', 'i18n', 'lib')
13
- require 'i18n'
14
- end
15
- # Advanced backend
16
- require 'backend/advanced'
5
+ require 'i18n'
17
6
 
18
- # Rails hacks
19
- require 'active_record_ext/custom_error_message' if defined?(ActiveRecord)
20
- if defined?(ActionView::Helpers)
21
- require 'action_view_ext/helpers/date_helper'
22
- require 'vendor/i18n_label/init'
23
- end
24
- require 'active_support_ext/parameterize' if defined?(ActiveSupport::Inflector)
7
+ $:.push File.join(File.dirname(__FILE__), 'russian')
8
+ require 'russian_rails'
25
9
 
26
10
  module Russian
27
11
  extend self
28
12
 
29
- module VERSION
30
- MAJOR = 0
31
- MINOR = 2
32
- TINY = 7
33
-
34
- STRING = [MAJOR, MINOR, TINY].join('.')
35
- end
13
+ autoload :Transliteration, 'transliteration'
36
14
 
37
15
  # Russian locale
38
16
  LOCALE = :'ru'
@@ -41,20 +19,21 @@ module Russian
41
19
  def locale
42
20
  LOCALE
43
21
  end
44
-
45
- # Returns custom backend class for usage with Russian library
46
- #
47
- # See I18n::Backend
48
- def i18n_backend_class
49
- I18n::Backend::Advanced
50
- end
51
-
52
- # Init Russian i18n: set custom backend, set default locale to Russian locale, load all translations
53
- # shipped with library.
22
+
23
+ # Regexp machers for context-based russian month names and day names translation
24
+ LOCALIZE_ABBR_MONTH_NAMES_MATCH = /(%d|%e)(.*)(%b)/
25
+ LOCALIZE_MONTH_NAMES_MATCH = /(%d|%e)(.*)(%B)/
26
+ LOCALIZE_STANDALONE_ABBR_DAY_NAMES_MATCH = /^%a/
27
+ LOCALIZE_STANDALONE_DAY_NAMES_MATCH = /^%A/
28
+
29
+ # Init Russian i18n: load all translations shipped with library.
54
30
  def init_i18n
55
- I18n.backend = Russian.i18n_backend_class.new
56
- I18n.default_locale = LOCALE
31
+ I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
32
+ I18n::Backend::Simple.send(:include, I18n::Backend::Transliterator)
33
+
57
34
  I18n.load_path.unshift(*locale_files)
35
+
36
+ I18n.reload!
58
37
  end
59
38
 
60
39
  # See I18n::translate
@@ -17,7 +17,7 @@
17
17
  # All date helpers support <tt>:use_standalone_month_names</tt> key now, <tt>select_month</tt> helper sets
18
18
  # it to true by default.
19
19
  # Standalone month names are also used when <tt>:discard_day</tt> key is provided.
20
- if defined?(ActionView::Helpers::DateTimeSelector) && ActionView::Helpers::DateTimeSelector.private_instance_methods.include?("translated_month_names")
20
+ if defined?(ActionView::Helpers::DateTimeSelector)
21
21
  module ActionView
22
22
  module Helpers
23
23
  module DateHelper
@@ -87,23 +87,29 @@ if defined?(ActionView::Helpers::DateTimeSelector) && ActionView::Helpers::DateT
87
87
  # убеждается, есть ли соотвествующие переводы в текущем языке и использует "отдельностоящие" названия
88
88
  # месяцев по необходимости
89
89
  def translated_month_names
90
- begin
91
- if @options[:use_short_month]
92
- if (@options[:discard_day] || @options[:use_standalone_month_names]) && I18n.translate(:'date.standalone_abbr_month_names')
90
+ if @options[:use_short_month]
91
+ if I18n.backend.send(:lookup, I18n.locale, :'date.common_abbr_month_names')
92
+ if (@options[:discard_day] || @options[:use_standalone_month_names])
93
93
  key = :'date.standalone_abbr_month_names'
94
94
  else
95
- key = :'date.abbr_month_names'
95
+ key = :'date.common_abbr_month_names'
96
96
  end
97
97
  else
98
- if (@options[:discard_day] || @options[:use_standalone_month_names]) && I18n.translate(:'date.standalone_month_names')
98
+ key = :'date.abbr_month_names'
99
+ end
100
+ else
101
+ if I18n.backend.send(:lookup, I18n.locale, :'date.common_month_names')
102
+ if (@options[:discard_day] || @options[:use_standalone_month_names])
99
103
  key = :'date.standalone_month_names'
100
104
  else
101
- key = :'date.month_names'
105
+ key = :'date.common_month_names'
102
106
  end
107
+ else
108
+ key = :'date.month_names'
103
109
  end
104
-
105
- I18n.translate(key, :locale => @options[:locale])
106
110
  end
111
+
112
+ I18n.translate(key, :locale => @options[:locale])
107
113
  end
108
114
 
109
115
  end
@@ -0,0 +1,70 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ if defined?(ActiveModel::Errors)
4
+ module ActiveModel
5
+ class Errors
6
+ # Redefine the ActiveModel::Errors.full_messages method:
7
+ # Returns all the full error messages in an array. 'Base' messages are handled as usual.
8
+ # Non-base messages are prefixed with the attribute name as usual UNLESS they begin with '^'
9
+ # in which case the attribute name is omitted.
10
+ # E.g. validates_acceptance_of :accepted_terms, :message => '^Please accept the terms of service'
11
+ #
12
+ # Переопределяет метод ActiveModel::Errors.full_messages. Сообщения об ошибках для атрибутов
13
+ # теперь не имеют префикса с названием атрибута если в сообщении об ошибке первым символом указан "^".
14
+ #
15
+ # Так, например,
16
+ #
17
+ # validates_acceptance_of :accepted_terms, :message => 'нужно принять соглашение'
18
+ #
19
+ # даст сообщение
20
+ #
21
+ # Accepted terms нужно принять соглашение
22
+ #
23
+ # однако,
24
+ #
25
+ # validates_acceptance_of :accepted_terms, :message => '^Нужно принять соглашение'
26
+ #
27
+ # даст сообщение
28
+ #
29
+ # Нужно принять соглашение
30
+ #
31
+ #
32
+ # Returns all the full error messages in an array.
33
+ #
34
+ # class Company
35
+ # validates_presence_of :name, :address, :email
36
+ # validates_length_of :name, :in => 5..30
37
+ # end
38
+ #
39
+ # company = Company.create(:address => '123 First St.')
40
+ # company.errors.full_messages # =>
41
+ # ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Address can't be blank"]
42
+ def full_messages
43
+ full_messages = []
44
+
45
+ each do |attribute, messages|
46
+ messages = Array.wrap(messages)
47
+ next if messages.empty?
48
+
49
+ if attribute == :base
50
+ messages.each {|m| full_messages << m }
51
+ else
52
+ attr_name = attribute.to_s.gsub('.', '_').humanize
53
+ attr_name = @base.class.human_attribute_name(attribute, :default => attr_name)
54
+ options = { :attribute => attr_name, :default => "%{attribute} %{message}" }
55
+
56
+ messages.each do |m|
57
+ if m =~ /^\^/
58
+ full_messages << m[1..-1]
59
+ else
60
+ full_messages << I18n.t(:"errors.format", options.merge(:message => m))
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ full_messages
67
+ end
68
+ end
69
+ end
70
+ end # if defined?
@@ -12,6 +12,8 @@ ru:
12
12
  delimiter: " "
13
13
  # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
14
14
  precision: 3
15
+ significant: false
16
+ strip_insignificant_zeros: false
15
17
 
16
18
  # Used in number_to_currency()
17
19
  currency:
@@ -26,6 +28,8 @@ ru:
26
28
  separator: "."
27
29
  delimiter: " "
28
30
  precision: 2
31
+ significant: false
32
+ strip_insignificant_zeros: false
29
33
 
30
34
  # Used in number_to_percentage()
31
35
  percentage:
@@ -49,11 +53,13 @@ ru:
49
53
  # separator:
50
54
  delimiter: ""
51
55
  precision: 1
56
+ significant: false
57
+ strip_insignificant_zeros: false
52
58
 
53
59
  # Rails 2.2
54
60
  # storage_units: [байт, КБ, МБ, ГБ, ТБ]
55
61
 
56
- # Rails 2.3
62
+ # Rails 2.3+
57
63
  storage_units:
58
64
  # Storage units output formatting.
59
65
  # %u is the storage unit, %n is the number (default: 2 MB)
@@ -69,6 +75,36 @@ ru:
69
75
  gb: "ГБ"
70
76
  tb: "ТБ"
71
77
 
78
+ decimal_units:
79
+ format: "%n %u"
80
+ units:
81
+ unit: ""
82
+ thousand:
83
+ one: "тысяча"
84
+ few: "тысяч"
85
+ many: "тысяч"
86
+ other: "тысяч"
87
+ million:
88
+ one: "миллион"
89
+ few: "миллионов"
90
+ many: "миллионов"
91
+ other: "миллионов"
92
+ billion:
93
+ one: "миллиард"
94
+ few: "миллиардов"
95
+ many: "миллиардов"
96
+ other: "миллиардов"
97
+ trillion:
98
+ one: "триллион"
99
+ few: "триллионов"
100
+ many: "триллионов"
101
+ other: "триллионов"
102
+ quadrillion:
103
+ one: "квадриллион"
104
+ few: "квадриллионов"
105
+ many: "квадриллионов"
106
+ other: "квадриллионов"
107
+
72
108
  # Используется в хелперах distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
73
109
  #
74
110
  #
@@ -77,60 +113,61 @@ ru:
77
113
  distance_in_words:
78
114
  half_a_minute: "меньше минуты"
79
115
  less_than_x_seconds:
80
- one: "меньше {{count}} секунды"
81
- few: "меньше {{count}} секунд"
82
- many: "меньше {{count}} секунд"
83
- other: "меньше {{count}} секунды"
116
+ one: "меньше %{count} секунды"
117
+ few: "меньше %{count} секунд"
118
+ many: "меньше %{count} секунд"
119
+ other: "меньше %{count} секунды"
84
120
  x_seconds:
85
- one: "{{count}} секунда"
86
- few: "{{count}} секунды"
87
- many: "{{count}} секунд"
88
- other: "{{count}} секунды"
121
+ one: "%{count} секунда"
122
+ few: "%{count} секунды"
123
+ many: "%{count} секунд"
124
+ other: "%{count} секунды"
89
125
  less_than_x_minutes:
90
- one: "меньше {{count}} минуты"
91
- few: "меньше {{count}} минут"
92
- many: "меньше {{count}} минут"
93
- other: "меньше {{count}} минуты"
126
+ one: "меньше %{count} минуты"
127
+ few: "меньше %{count} минут"
128
+ many: "меньше %{count} минут"
129
+ other: "меньше %{count} минуты"
94
130
  x_minutes:
95
- one: "{{count}} минуту"
96
- few: "{{count}} минуты"
97
- many: "{{count}} минут"
98
- other: "{{count}} минуты"
131
+ one: "%{count} минута"
132
+ few: "%{count} минуты"
133
+ many: "%{count} минут"
134
+ other: "%{count} минуты"
99
135
  about_x_hours:
100
- one: "около {{count}} часа"
101
- few: "около {{count}} часов"
102
- many: "около {{count}} часов"
103
- other: "около {{count}} часа"
136
+ one: "около %{count} часа"
137
+ few: "около %{count} часов"
138
+ many: "около %{count} часов"
139
+ other: "около %{count} часа"
104
140
  x_days:
105
- one: "{{count}} день"
106
- few: "{{count}} дня"
107
- many: "{{count}} дней"
108
- other: "{{count}} дня"
141
+ one: "%{count} день"
142
+ few: "%{count} дня"
143
+ many: "%{count} дней"
144
+ other: "%{count} дня"
109
145
  about_x_months:
110
- one: "около {{count}} месяца"
111
- few: "около {{count}} месяцев"
112
- many: "около {{count}} месяцев"
113
- other: "около {{count}} месяца"
146
+ one: "около %{count} месяца"
147
+ few: "около %{count} месяцев"
148
+ many: "около %{count} месяцев"
149
+ other: "около %{count} месяца"
114
150
  x_months:
115
- one: "{{count}} месяц"
116
- few: "{{count}} месяца"
117
- many: "{{count}} месяцев"
118
- other: "{{count}} месяца"
151
+ one: "%{count} месяц"
152
+ few: "%{count} месяца"
153
+ many: "%{count} месяцев"
154
+ other: "%{count} месяца"
119
155
  about_x_years:
120
- one: "около {{count}} года"
121
- few: "около {{count}} лет"
122
- many: "около {{count}} лет"
123
- other: "около {{count}} лет"
156
+ one: "около %{count} года"
157
+ few: "около %{count} лет"
158
+ many: "около %{count} лет"
159
+ other: "около %{count} лет"
124
160
  over_x_years:
125
- one: "больше {{count}} года"
126
- few: "больше {{count}} лет"
127
- many: "больше {{count}} лет"
128
- other: "больше {{count}} лет"
161
+ one: "больше %{count} года"
162
+ few: "больше %{count} лет"
163
+ many: "больше %{count} лет"
164
+ other: "больше %{count} лет"
129
165
  almost_x_years:
130
- one: "почти {{count}} год"
131
- few: "почти {{count}} года"
132
- many: "почти {{count}} лет"
133
- other: "почти {{count}} лет"
166
+ one: "почти %{count} год"
167
+ few: "почти %{count} года"
168
+ many: "почти %{count} лет"
169
+ other: "почти %{count} лет"
170
+
134
171
  prompts:
135
172
  year: "Год"
136
173
  month: "Месяц"
@@ -145,12 +182,12 @@ ru:
145
182
  template:
146
183
  # Заголовок сообщения об ошибке
147
184
  header:
148
- one: "{{model}}: сохранение не удалось из-за {{count}} ошибки"
149
- few: "{{model}}: сохранение не удалось из-за {{count}} ошибок"
150
- many: "{{model}}: сохранение не удалось из-за {{count}} ошибок"
151
- other: "{{model}}: сохранение не удалось из-за {{count}} ошибки"
185
+ one: "%{model}: сохранение не удалось из-за %{count} ошибки"
186
+ few: "%{model}: сохранение не удалось из-за %{count} ошибок"
187
+ many: "%{model}: сохранение не удалось из-за %{count} ошибок"
188
+ other: "%{model}: сохранение не удалось из-за %{count} ошибки"
152
189
 
153
- # Первый параграф сообщения об ошибке. Можно использовать макрос {{count}}
190
+ # Первый параграф сообщения об ошибке. Можно использовать макрос %{count}
154
191
  #
155
192
  #
156
193
  # The variable :count is also available
@@ -160,3 +197,16 @@ ru:
160
197
  select:
161
198
  # default value for :prompt => true in FormOptionsHelper
162
199
  prompt: "Выберите: "
200
+
201
+ helpers:
202
+ select:
203
+ # default value for :prompt => true in FormOptionsHelper
204
+ prompt: "Выберите: "
205
+
206
+
207
+ # Default translation keys for submit FormHelper
208
+ submit:
209
+ create: 'Создать %{model}'
210
+ update: 'Сохранить %{model}'
211
+ submit: 'Сохранить %{model}'
212
+
@@ -0,0 +1,50 @@
1
+ ru:
2
+ errors:
3
+ format: "%{attribute} %{message}"
4
+
5
+ messages:
6
+ inclusion: "имеет непредусмотренное значение"
7
+ exclusion: "имеет зарезервированное значение"
8
+ invalid: "имеет неверное значение"
9
+ confirmation: "не совпадает с подтверждением"
10
+ accepted: "нужно подтвердить"
11
+ empty: "не может быть пустым"
12
+ blank: "не может быть пустым"
13
+ too_long:
14
+ one: "слишком большой длины (не может быть больше чем %{count} символ)"
15
+ few: "слишком большой длины (не может быть больше чем %{count} символа)"
16
+ many: "слишком большой длины (не может быть больше чем %{count} символов)"
17
+ other: "слишком большой длины (не может быть больше чем %{count} символа)"
18
+ too_short:
19
+ one: "недостаточной длины (не может быть меньше %{count} символа)"
20
+ few: "недостаточной длины (не может быть меньше %{count} символов)"
21
+ many: "недостаточной длины (не может быть меньше %{count} символов)"
22
+ other: "недостаточной длины (не может быть меньше %{count} символа)"
23
+ wrong_length:
24
+ one: "неверной длины (может быть длиной ровно %{count} символ)"
25
+ few: "неверной длины (может быть длиной ровно %{count} символа)"
26
+ many: "неверной длины (может быть длиной ровно %{count} символов)"
27
+ other: "неверной длины (может быть длиной ровно %{count} символа)"
28
+ taken: "уже существует"
29
+ not_a_number: "не является числом"
30
+ not_an_integer: "не является целым числом"
31
+ greater_than: "может иметь значение большее %{count}"
32
+ greater_than_or_equal_to: "может иметь значение большее или равное %{count}"
33
+ equal_to: "может иметь лишь значение, равное %{count}"
34
+ less_than: "может иметь значение меньшее чем %{count}"
35
+ less_than_or_equal_to: "может иметь значение меньшее или равное %{count}"
36
+ odd: "может иметь лишь четное значение"
37
+ even: "может иметь лишь нечетное значение"
38
+ record_invalid: "Возникли ошибки: %{errors}"
39
+
40
+ template:
41
+ # Заголовок сообщения об ошибке
42
+ header:
43
+ one: "%{model}: сохранение не удалось из-за %{count} ошибки"
44
+ few: "%{model}: сохранение не удалось из-за %{count} ошибок"
45
+ many: "%{model}: сохранение не удалось из-за %{count} ошибок"
46
+ other: "%{model}: сохранение не удалось из-за %{count} ошибки"
47
+
48
+ # Первый параграф сообщения об ошибке. Можно использовать макрос %{count}
49
+ # The variable :count is also available
50
+ body: "Проблемы возникли со следующими полями:"