krasivotokak-russian 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/CHANGELOG +64 -0
  2. data/LICENSE +20 -0
  3. data/README.textile +288 -0
  4. data/Rakefile +55 -0
  5. data/TODO +10 -0
  6. data/init.rb +3 -0
  7. data/lib/russian.rb +119 -0
  8. data/lib/russian/action_view_ext/helpers/date_helper.rb +112 -0
  9. data/lib/russian/active_record_ext/custom_error_message.rb +67 -0
  10. data/lib/russian/active_support_ext/parameterize.rb +31 -0
  11. data/lib/russian/backend/advanced.rb +132 -0
  12. data/lib/russian/locale/actionview.yml +153 -0
  13. data/lib/russian/locale/activerecord.yml +90 -0
  14. data/lib/russian/locale/activesupport.yml +16 -0
  15. data/lib/russian/locale/datetime.yml +46 -0
  16. data/lib/russian/locale/pluralize.rb +36 -0
  17. data/lib/russian/transliteration.rb +60 -0
  18. data/lib/vendor/i18n/MIT-LICENSE +20 -0
  19. data/lib/vendor/i18n/README.textile +20 -0
  20. data/lib/vendor/i18n/Rakefile +5 -0
  21. data/lib/vendor/i18n/i18n.gemspec +27 -0
  22. data/lib/vendor/i18n/lib/i18n.rb +199 -0
  23. data/lib/vendor/i18n/lib/i18n/backend/simple.rb +214 -0
  24. data/lib/vendor/i18n/lib/i18n/exceptions.rb +53 -0
  25. data/lib/vendor/i18n/test/all.rb +5 -0
  26. data/lib/vendor/i18n/test/i18n_exceptions_test.rb +100 -0
  27. data/lib/vendor/i18n/test/i18n_test.rb +125 -0
  28. data/lib/vendor/i18n/test/locale/en.rb +1 -0
  29. data/lib/vendor/i18n/test/locale/en.yml +3 -0
  30. data/lib/vendor/i18n/test/simple_backend_test.rb +568 -0
  31. data/lib/vendor/i18n_label/README.textile +38 -0
  32. data/lib/vendor/i18n_label/Rakefile +11 -0
  33. data/lib/vendor/i18n_label/init.rb +1 -0
  34. data/lib/vendor/i18n_label/install.rb +1 -0
  35. data/lib/vendor/i18n_label/lib/i18n_label.rb +23 -0
  36. data/lib/vendor/i18n_label/spec/i18n_label_spec.rb +20 -0
  37. data/lib/vendor/i18n_label/spec/spec_helper.rb +10 -0
  38. data/lib/vendor/i18n_label/tasks/i18n_label_tasks.rake +4 -0
  39. data/lib/vendor/i18n_label/uninstall.rb +1 -0
  40. data/spec/fixtures/en.yml +4 -0
  41. data/spec/fixtures/ru.yml +4 -0
  42. data/spec/i18n/locale/datetime_spec.rb +93 -0
  43. data/spec/i18n/locale/pluralization_spec.rb +28 -0
  44. data/spec/locale_spec.rb +123 -0
  45. data/spec/russian_spec.rb +136 -0
  46. data/spec/spec_helper.rb +7 -0
  47. data/spec/transliteration_spec.rb +44 -0
  48. metadata +125 -0
@@ -0,0 +1,112 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ # Заменяет хелпер Rails <tt>select_month</tt> и метод <tt>translated_month_names</tt>
4
+ # для поддержки функционала "отдельностоящих имен месяцев".
5
+ #
6
+ # Теперь можно использовать и полные, и сокращенные название месяцев в двух вариантах -- контекстном
7
+ # (по умолчанию) и отдельностоящем (если в текущем языке есть соответствующие переводы).
8
+ # Теперь хелперы поддерживают ключ <tt>:use_standalone_month_names</tt>, хелпер <tt>select_month</tt>
9
+ # устанавливает его по умолчанию.
10
+ # Отдельностоящие имена месяцев также используютс когда указан ключ <tt>:discard_day</tt>.
11
+ #
12
+ #
13
+ # Replaces Rails <tt>select_month</tt> helper and <tt>translated_month_names</tt> private method to provide
14
+ # "standalone month names" feature.
15
+ #
16
+ # It is now possible to use both abbreviated and full month names in two variants (if current locale provides them).
17
+ # All date helpers support <tt>:use_standalone_month_names</tt> key now, <tt>select_month</tt> helper sets
18
+ # it to true by default.
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")
21
+ module ActionView
22
+ module Helpers
23
+ module DateHelper
24
+ # Returns a select tag with options for each of the months January through December with the current month
25
+ # selected. The month names are presented as keys (what's shown to the user) and the month numbers (1-12) are
26
+ # used as values (what's submitted to the server). It's also possible to use month numbers for the presentation
27
+ # instead of names -- set the <tt>:use_month_numbers</tt> key in +options+ to true for this to happen. If you
28
+ # want both numbers and names, set the <tt>:add_month_numbers</tt> key in +options+ to true. If you would prefer
29
+ # to show month names as abbreviations, set the <tt>:use_short_month</tt> key in +options+ to true. If you want
30
+ # to use your own month names, set the <tt>:use_month_names</tt> key in +options+ to an array of 12 month names.
31
+ # You can also choose if you want to use i18n standalone month names or default month names -- you can
32
+ # force standalone month names usage by using <tt>:use_standalone_month_names</tt> key.
33
+ # Override the field name using the <tt>:field_name</tt> option, 'month' by default.
34
+ #
35
+ #
36
+ # Также поддерживается ключ <tt>:use_standalone_month_names</tt> для явного указания о необходимости
37
+ # использования отдельностоящих имен месяцев, если текущий язык их поддерживает.
38
+ #
39
+ #
40
+ # ==== Examples
41
+ # # Generates a select field for months that defaults to the current month that
42
+ # # will use keys like "January", "March".
43
+ # select_month(Date.today)
44
+ #
45
+ # # Generates a select field for months that defaults to the current month that
46
+ # # is named "start" rather than "month"
47
+ # select_month(Date.today, :field_name => 'start')
48
+ #
49
+ # # Generates a select field for months that defaults to the current month that
50
+ # # will use keys like "1", "3".
51
+ # select_month(Date.today, :use_month_numbers => true)
52
+ #
53
+ # # Generates a select field for months that defaults to the current month that
54
+ # # will use keys like "1 - January", "3 - March".
55
+ # select_month(Date.today, :add_month_numbers => true)
56
+ #
57
+ # # Generates a select field for months that defaults to the current month that
58
+ # # will use keys like "Jan", "Mar".
59
+ # select_month(Date.today, :use_short_month => true)
60
+ #
61
+ # # Generates a select field for months that defaults to the current month that
62
+ # # will use keys like "Januar", "Marts."
63
+ # select_month(Date.today, :use_month_names => %w(Januar Februar Marts ...))
64
+ #
65
+ def select_month(date, options = {}, html_options = {})
66
+ DateTimeSelector.new(date, options.merge(:use_standalone_month_names => true), html_options).select_month
67
+ end
68
+ end
69
+
70
+ class DateTimeSelector #:nodoc:
71
+ private
72
+ # Returns translated month names
73
+ # => [nil, "January", "February", "March",
74
+ # "April", "May", "June", "July",
75
+ # "August", "September", "October",
76
+ # "November", "December"]
77
+ #
78
+ # If :use_short_month option is set
79
+ # => [nil, "Jan", "Feb", "Mar", "Apr", "May", "Jun",
80
+ # "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
81
+ #
82
+ # Also looks up if <tt>:discard_day</tt> or <tt>:use_standalone_month_names</tt> option is set
83
+ # and uses i18n standalone month names if so.
84
+ #
85
+ #
86
+ # Также в зависимости от использования ключей <tt>:discard_day</tt> или <tt>:use_standalone_month_names</tt>
87
+ # убеждается, есть ли соотвествующие переводы в текущем языке и использует "отдельностоящие" названия
88
+ # месяцев по необходимости
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')
93
+ key = :'date.standalone_abbr_month_names'
94
+ else
95
+ key = :'date.abbr_month_names'
96
+ end
97
+ else
98
+ if (@options[:discard_day] || @options[:use_standalone_month_names]) && I18n.translate(:'date.standalone_month_names')
99
+ key = :'date.standalone_month_names'
100
+ else
101
+ key = :'date.month_names'
102
+ end
103
+ end
104
+
105
+ I18n.translate(key, :locale => @options[:locale])
106
+ end
107
+ end
108
+
109
+ end
110
+ end
111
+ end
112
+ end # if defined?
@@ -0,0 +1,67 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ # The following is taken from custom_error_message plugin by David Easley
4
+ # (http://rubyforge.org/projects/custom-err-msg/)
5
+ module ActiveRecord
6
+ if Rails.version < '2.3.4'
7
+ class Errors
8
+
9
+ # Redefine the ActiveRecord::Errors::full_messages method:
10
+ # Returns all the full error messages in an array. 'Base' messages are handled as usual.
11
+ # Non-base messages are prefixed with the attribute name as usual UNLESS they begin with '^'
12
+ # in which case the attribute name is omitted.
13
+ # E.g. validates_acceptance_of :accepted_terms, :message => '^Please accept the terms of service'
14
+ #
15
+ #
16
+ # Переопределяет метод ActiveRecord::Errors::full_messages. Сообщения об ошибках для атрибутов
17
+ # теперь не имеют префикса с названием атрибута если в сообщении об ошибке первым символом указан "^".
18
+ #
19
+ # Так, например,
20
+ #
21
+ # validates_acceptance_of :accepted_terms, :message => 'нужно принять соглашение'
22
+ #
23
+ # даст сообщение
24
+ #
25
+ # Accepted terms нужно принять соглашение
26
+ #
27
+ # однако,
28
+ #
29
+ # validates_acceptance_of :accepted_terms, :message => '^Нужно принять соглашение'
30
+ #
31
+ # даст сообщение
32
+ #
33
+ # Нужно принять соглашение
34
+ def full_messages
35
+ full_messages = []
36
+
37
+ @errors.each_key do |attr|
38
+ @errors[attr].each do |msg|
39
+ next if msg.nil?
40
+
41
+ if attr == "base"
42
+ full_messages << msg
43
+ elsif msg =~ /^\^/
44
+ full_messages << msg[1..-1]
45
+ else
46
+ full_messages << @base.class.human_attribute_name(attr) + " " + msg
47
+ end
48
+ end
49
+ end
50
+
51
+ return full_messages
52
+ end
53
+ end
54
+ else
55
+ #class Error
56
+ # def full_message
57
+ # case attribute.to_s
58
+ # when 'base'
59
+ # message
60
+ # when /^\^/
61
+ # else
62
+ # generate_full_message(message, options.dup)
63
+ # end
64
+ # end
65
+ #end
66
+ end
67
+ end
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module ActiveSupport
4
+ module Inflector
5
+ # Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
6
+ # Transliterates all russian characters in string first, then passes it to ActiveSupport Inflector.
7
+ #
8
+ # Заменяет все спецсимволы в строке так, что результат может использоваться как часть "красивого" URL.
9
+ # От стандартного ActiveSupport Inflector отличается тем, что сначала производится транслитерация
10
+ # букв русского алфавита.
11
+ #
12
+ # ==== Examples
13
+ #
14
+ # class Person
15
+ # def to_param
16
+ # "#{id}-#{name.parameterize}"
17
+ # end
18
+ # end
19
+ #
20
+ # @person = Person.find(1)
21
+ # # => #<Person id: 1, name: "Дональд Кнут">
22
+ #
23
+ # <%= link_to(@person.name, person_path %>
24
+ # # => <a href="/person/1-donald-knut">Дональд Кнут</a>
25
+ def parameterize_with_russian(string, sep = '-')
26
+ parameterize_without_russian(Russian::transliterate(string), sep)
27
+ end
28
+ alias_method :parameterize_without_russian, :parameterize
29
+ alias_method :parameterize, :parameterize_with_russian
30
+ end
31
+ end
@@ -0,0 +1,132 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module I18n
4
+ module Backend
5
+ # "Продвинутый" бекэнд для I18n.
6
+ #
7
+ # Наследует Simple бекэнд и полностью с ним совместим. Добаляет поддержку
8
+ # для отдельностоящих/контекстных названий дней недели и месяцев.
9
+ # Также позволяет каждому языку использовать собственные правила плюрализации,
10
+ # объявленные как Proc (<tt>lambda</tt>).
11
+ #
12
+ #
13
+ # Advanced I18n backend.
14
+ #
15
+ # Extends Simple backend. Allows usage of "standalone" keys
16
+ # for DateTime localization and usage of user-defined Proc (lambda) pluralization
17
+ # methods in translation tables.
18
+ class Advanced < Simple
19
+ LOCALIZE_ABBR_MONTH_NAMES_MATCH = /(%d|%e)?(\s*)(%b)/
20
+ LOCALIZE_MONTH_NAMES_MATCH = /(%d|%e)?(\s*)(%B)/
21
+ LOCALIZE_STANDALONE_ABBR_DAY_NAMES_MATCH = /^%a/
22
+ LOCALIZE_STANDALONE_DAY_NAMES_MATCH = /^%A/
23
+
24
+ # Acts the same as +strftime+, but returns a localized version of the
25
+ # formatted date string. Takes a key from the date/time formats
26
+ # translations as a format argument (<em>e.g.</em>, <tt>:short</tt> in <tt>:'date.formats'</tt>).
27
+ #
28
+ #
29
+ # Метод отличается от <tt>localize</tt> в Simple бекэнде поддержкой
30
+ # отдельностоящих/контекстных названий дней недели и месяцев.
31
+ #
32
+ #
33
+ # Note that it differs from <tt>localize</tt> in Simple< backend by checking for
34
+ # "standalone" month name/day name keys in translation and using them if available.
35
+ def localize(locale, object, format = :default)
36
+ raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime)
37
+
38
+ type = object.respond_to?(:sec) ? 'time' : 'date'
39
+ # TODO only translate these if format is a String?
40
+ formats = translate(locale, :"#{type}.formats")
41
+ format = formats[format.to_sym] if formats && formats[format.to_sym]
42
+ # TODO raise exception unless format found?
43
+ format = format.to_s.dup
44
+
45
+ # TODO only translate these if the format string is actually present
46
+ # TODO check which format strings are present, then bulk translate then, then replace them
47
+
48
+ if lookup(locale, :"date.standalone_abbr_day_names")
49
+ format.gsub!(LOCALIZE_STANDALONE_ABBR_DAY_NAMES_MATCH,
50
+ translate(locale, :"date.standalone_abbr_day_names")[object.wday])
51
+ end
52
+ format.gsub!(/%a/, translate(locale, :"date.abbr_day_names")[object.wday])
53
+
54
+ if lookup(locale, :"date.standalone_day_names")
55
+ format.gsub!(LOCALIZE_STANDALONE_DAY_NAMES_MATCH,
56
+ translate(locale, :"date.standalone_day_names")[object.wday])
57
+ end
58
+ format.gsub!(/%A/, translate(locale, :"date.day_names")[object.wday])
59
+
60
+ if lookup(locale, :"date.standalone_abbr_month_names")
61
+ format.gsub!(LOCALIZE_ABBR_MONTH_NAMES_MATCH) do
62
+ $1 ? $1 + $2 + translate(locale, :"date.abbr_month_names")[object.mon] :
63
+ $2 + translate(locale, :"date.standalone_abbr_month_names")[object.mon]
64
+ end
65
+ else
66
+ format.gsub!(/%b/, translate(locale, :"date.abbr_month_names")[object.mon])
67
+ end
68
+
69
+ if lookup(locale, :"date.standalone_month_names")
70
+ format.gsub!(LOCALIZE_MONTH_NAMES_MATCH) do
71
+ $1 ? $1 + $2 + translate(locale, :"date.month_names")[object.mon] :
72
+ $2 + translate(locale, :"date.standalone_month_names")[object.mon]
73
+ end
74
+ else
75
+ format.gsub!(/%B/, translate(locale, :"date.month_names")[object.mon])
76
+ end
77
+
78
+ format.gsub!(/%p/, translate(locale, :"time.#{object.hour < 12 ? :am : :pm}")) if object.respond_to? :hour
79
+ object.strftime(format)
80
+ end
81
+
82
+ protected
83
+ # Использует правила плюрализации из таблицы переводов для языка (если присутствуют),
84
+ # иначе использует правило плюрализации по умолчанию (английский язык).
85
+ #
86
+ # Пример задания правила в таблице переводов:
87
+ #
88
+ # store_translations :'en', {
89
+ # :pluralize => lambda { |n| n == 1 ? :one : :other }
90
+ # }
91
+ #
92
+ # Правило должно возвращать один из символов для таблицы переводов:
93
+ # :zero, :one, :two, :few, :many, :other
94
+ #
95
+ #
96
+ # Picks a pluralization rule specified in translation tables for a language or
97
+ # uses default pluralization rules.
98
+ #
99
+ # This is how pluralization rules are defined in translation tables, English
100
+ # language for example:
101
+ #
102
+ # store_translations :'en', {
103
+ # :pluralize => lambda { |n| n == 1 ? :one : :other }
104
+ # }
105
+ #
106
+ # Rule must return a symbol to use with pluralization, it must be one of:
107
+ # :zero, :one, :two, :few, :many, :other
108
+ def pluralize(locale, entry, count)
109
+ return entry unless entry.is_a?(Hash) and count
110
+
111
+ key = :zero if count == 0 && entry.has_key?(:zero)
112
+ locale_pluralize = lookup(locale, :pluralize)
113
+ if locale_pluralize && locale_pluralize.respond_to?(:call)
114
+ key ||= locale_pluralize.call(count)
115
+ else
116
+ key ||= default_pluralizer(count)
117
+ end
118
+ raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
119
+
120
+ entry[key]
121
+ end
122
+
123
+ # Default pluralizer, used if pluralization rule is not defined in translations.
124
+ #
125
+ # Uses English pluralization rules -- it will pick the first translation if count is not equal to 1
126
+ # and the second translation if it is equal to 1.
127
+ def default_pluralizer(count)
128
+ count == 1 ? :one : :other
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,153 @@
1
+ ru:
2
+ number:
3
+ # Используется в number_with_delimiter()
4
+ # Также является установками по умолчанию для 'currency', 'percentage', 'precision', 'human'
5
+ #
6
+ # Used in number_with_delimiter()
7
+ # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
8
+ format:
9
+ # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
10
+ separator: "."
11
+ # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
12
+ delimiter: " "
13
+ # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
14
+ precision: 3
15
+
16
+ # Used in number_to_currency()
17
+ currency:
18
+ format:
19
+ # Формат отображения валюты и обозначение самой валюты
20
+ #
21
+ #
22
+ # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
23
+ format: "%n %u"
24
+ unit: "руб."
25
+ # These three are to override number.format and are optional
26
+ separator: "."
27
+ delimiter: " "
28
+ precision: 2
29
+
30
+ # Used in number_to_percentage()
31
+ percentage:
32
+ format:
33
+ # These three are to override number.format and are optional
34
+ # separator:
35
+ delimiter: ""
36
+
37
+ # Used in number_to_precision()
38
+ precision:
39
+ format:
40
+ # These three are to override number.format and are optional
41
+ # separator:
42
+ delimiter: ""
43
+ # precision:
44
+
45
+ # Used in number_to_human_size()
46
+ human:
47
+ format:
48
+ # These three are to override number.format and are optional
49
+ # separator:
50
+ delimiter: ""
51
+ precision: 1
52
+
53
+ # Rails 2.2
54
+ # storage_units: [байт, КБ, МБ, ГБ, ТБ]
55
+
56
+ # Rails 2.3
57
+ storage_units:
58
+ # Storage units output formatting.
59
+ # %u is the storage unit, %n is the number (default: 2 MB)
60
+ format: "%n %u"
61
+ units:
62
+ byte:
63
+ one: "байт"
64
+ few: "байта"
65
+ many: "байт"
66
+ other: "байта"
67
+ kb: "КБ"
68
+ mb: "МБ"
69
+ gb: "ГБ"
70
+ tb: "ТБ"
71
+
72
+ # Используется в хелперах distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
73
+ #
74
+ #
75
+ # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
76
+ datetime:
77
+ distance_in_words:
78
+ half_a_minute: "меньше минуты"
79
+ less_than_x_seconds:
80
+ one: "меньше {{count}} секунды"
81
+ few: "меньше {{count}} секунд"
82
+ many: "меньше {{count}} секунд"
83
+ other: "меньше {{count}} секунды"
84
+ x_seconds:
85
+ one: "{{count}} секунда"
86
+ few: "{{count}} секунды"
87
+ many: "{{count}} секунд"
88
+ other: "{{count}} секунды"
89
+ less_than_x_minutes:
90
+ one: "меньше {{count}} минуты"
91
+ few: "меньше {{count}} минут"
92
+ many: "меньше {{count}} минут"
93
+ other: "меньше {{count}} минуты"
94
+ x_minutes:
95
+ one: "{{count}} минуту"
96
+ few: "{{count}} минуты"
97
+ many: "{{count}} минут"
98
+ other: "{{count}} минуты"
99
+ about_x_hours:
100
+ one: "около {{count}} часа"
101
+ few: "около {{count}} часов"
102
+ many: "около {{count}} часов"
103
+ other: "около {{count}} часа"
104
+ x_days:
105
+ one: "{{count}} день"
106
+ few: "{{count}} дня"
107
+ many: "{{count}} дней"
108
+ other: "{{count}} дня"
109
+ about_x_months:
110
+ one: "около {{count}} месяца"
111
+ few: "около {{count}} месяцев"
112
+ many: "около {{count}} месяцев"
113
+ other: "около {{count}} месяца"
114
+ x_months:
115
+ one: "{{count}} месяц"
116
+ few: "{{count}} месяца"
117
+ many: "{{count}} месяцев"
118
+ other: "{{count}} месяца"
119
+ about_x_years:
120
+ one: "около {{count}} года"
121
+ few: "около {{count}} лет"
122
+ many: "около {{count}} лет"
123
+ other: "около {{count}} лет"
124
+ over_x_years:
125
+ one: "больше {{count}} года"
126
+ few: "больше {{count}} лет"
127
+ many: "больше {{count}} лет"
128
+ other: "больше {{count}} лет"
129
+ prompts:
130
+ year: "Год"
131
+ month: "Месяц"
132
+ day: "День"
133
+ hour: "Часов"
134
+ minute: "Минут"
135
+ second: "Секунд"
136
+
137
+ # Используется в хелпере error_messages_for
138
+ activerecord:
139
+ errors:
140
+ template:
141
+ # Заголовок сообщения об ошибке
142
+ header:
143
+ one: "{{model}}: сохранение не удалось из-за {{count}} ошибки"
144
+ few: "{{model}}: сохранение не удалось из-за {{count}} ошибок"
145
+ many: "{{model}}: сохранение не удалось из-за {{count}} ошибок"
146
+ other: "{{model}}: сохранение не удалось из-за {{count}} ошибки"
147
+
148
+ # Первый параграф сообщения об ошибке. Можно использовать макрос {{count}}
149
+ #
150
+ #
151
+ # The variable :count is also available
152
+ body: "Проблемы возникли со следующими полями:"
153
+