From 8b32b36dd073238bc4612553cb6c17db214dfa60 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 18 Sep 2024 16:27:55 -0400 Subject: [PATCH] Fix method redefinition warnings when pluralizations are reloaded Fix: https://github.com/svenfuchs/rails-i18n/issues/735 Whenever pluralization rules are reloaded it causes a lot of warnings: ``` lib/rails_i18n/../../rails/pluralization/ar.rb:4: warning: method redefined; discarding old rule lib/rails_i18n/../../rails/pluralization/ar.rb:4: warning: previous definition of rule was here lib/rails_i18n/../../rails/pluralization/gd.rb:4: warning: method redefined; discarding old rule lib/rails_i18n/../../rails/pluralization/gd.rb:4: warning: previous definition of rule was here lib/rails_i18n/../../rails/pluralization/hsb.rb:4: warning: method redefined; discarding old rule lib/rails_i18n/../../rails/pluralization/hsb.rb:4: warning: previous definition of rule was here lib/rails_i18n/../../rails/pluralization/lt.rb:4: warning: method redefined; discarding old rule lib/rails_i18n/../../rails/pluralization/lt.rb:4: warning: previous definition of rule was here lib/rails_i18n/../../rails/pluralization/lv.rb:4: warning: method redefined; discarding old rule lib/rails_i18n/../../rails/pluralization/lv.rb:4: warning: previous definition of rule was here lib/rails_i18n/../../rails/pluralization/mk.rb:4: warning: method redefined; discarding old rule lib/rails_i18n/../../rails/pluralization/mk.rb:4: warning: previous definition of rule was here lib/rails_i18n/../../rails/pluralization/pl.rb:4: warning: method redefined; discarding old rule lib/rails_i18n/../../rails/pluralization/pl.rb:4: warning: previous definition of rule was here lib/rails_i18n/../../rails/pluralization/sl.rb:4: warning: method redefined; discarding old rule lib/rails_i18n/../../rails/pluralization/sl.rb:4: warning: previous definition of rule was here ... ``` This is mostly harmless, but annoying for users who try to run with no warnings at all. --- CHANGELOG.md | 3 +- lib/rails_i18n/pluralization.rb | 143 ++++++++++++++++++++++ lib/rails_i18n/transliteration.rb | 191 ++++++++++++++++++++++++++++++ rails/pluralization/ar.rb | 28 +---- rails/pluralization/gd.rb | 24 +--- rails/pluralization/hsb.rb | 21 +--- rails/pluralization/lt.rb | 23 +--- rails/pluralization/lv.rb | 16 +-- rails/pluralization/mk.rb | 16 +-- rails/pluralization/pl.rb | 25 +--- rails/pluralization/sl.rb | 19 +-- rails/transliteration/ru.rb | 89 +------------- rails/transliteration/uk.rb | 109 +---------------- 13 files changed, 346 insertions(+), 361 deletions(-) create mode 100644 lib/rails_i18n/pluralization.rb create mode 100644 lib/rails_i18n/transliteration.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 914bcb9db..c7e01da5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ - Portuguese (pt): Fixed `number.currency.format.format` and `helpers.submit.update` #1122 - Croatian (hr): use genitive case for month names and put a period after weekday and month abbreviations #1126 - Korean (ko): Add missing keys (Storage units) #1118 - - Fix compatibility with frozen string literals. #1120 +- Fix compatibility with frozen string literals. #1120 +- Refactor translations implemented in Ruby to avoid method redefinition warnings on reload. #1128 ## 7.0.9 (2024-03-13) diff --git a/lib/rails_i18n/pluralization.rb b/lib/rails_i18n/pluralization.rb new file mode 100644 index 000000000..becbcb3f5 --- /dev/null +++ b/lib/rails_i18n/pluralization.rb @@ -0,0 +1,143 @@ +module RailsI18n + module Pluralization + module Arabic + def self.rule + lambda do |n| + return :other unless n.is_a?(Numeric) + + mod100 = n % 100 + + if n == 0 + :zero + elsif n == 1 + :one + elsif n == 2 + :two + elsif (3..10).to_a.include?(mod100) + :few + elsif (11..99).to_a.include?(mod100) + :many + else + :other + end + end + end + end + + module ScottishGaelic + def self.rule + lambda do |n| + return :other unless n.is_a?(Numeric) + + floorn = n.floor + + if floorn == 1 || floorn == 11 + :one + elsif floorn == 2 || floorn == 12 + :two + elsif (3..19).member?(floorn) + :few + else + :other + end + end + end + end + + module UpperSorbian + def self.rule + lambda do |n| + return :other unless n.is_a?(Numeric) + + mod100 = n % 100 + + case mod100 + when 1 then :one + when 2 then :two + when 3, 4 then :few + else :other + end + end + end + end + + module Lithuanian + def self.rule + lambda do |n| + return :other unless n.is_a?(Numeric) + + mod10 = n % 10 + mod100 = n % 100 + + if mod10 == 1 && !(11..19).to_a.include?(mod100) + :one + elsif (2..9).to_a.include?(mod10) && !(11..19).to_a.include?(mod100) + :few + else + :other + end + end + end + end + + module Latvian + def self.rule + lambda do |n| + if n.is_a?(Numeric) && n % 10 == 1 && n % 100 != 11 + :one + else + :other + end + end + end + end + + module Macedonian + def self.rule + lambda do |n| + if n.is_a?(Numeric) && n % 10 == 1 && n != 11 + :one + else + :other + end + end + end + end + + module Polish + def self.rule + lambda do |n| + return :other unless n.is_a?(Numeric) + + mod10 = n % 10 + mod100 = n % 100 + + if n == 1 + :one + elsif [2, 3, 4].include?(mod10) && ![12, 13, 14].include?(mod100) + :few + elsif [0, 1, 5, 6, 7, 8, 9].include?(mod10) || [12, 13, 14].include?(mod100) + :many + else + :other + end + end + end + end + + module Slovenian + def self.rule + lambda do |n| + return :other unless n.is_a?(Numeric) + + case n % 100 + when 1 then :one + when 2 then :two + when 3, 4 then :few + else :other + end + end + end + end + end +end diff --git a/lib/rails_i18n/transliteration.rb b/lib/rails_i18n/transliteration.rb new file mode 100644 index 000000000..438ddc9ad --- /dev/null +++ b/lib/rails_i18n/transliteration.rb @@ -0,0 +1,191 @@ +# frozen_string_literal: true + +module RailsI18n + module Transliteration + module Ukrainian + class << self + def rule + lambda do |string| + next '' unless string + + string.gsub(/./) do |char| + # Regexp.last_match is local to the thread and method scope + # of the method that did the pattern match. + @pre_match, @post_match = $`, $' + + case char + when 'Ж' + lookahead_upcase 'ZH' + when 'Х' + lookahead_upcase 'KH' + when 'Ц' + lookahead_upcase 'TS' + when 'Ч' + lookahead_upcase 'CH' + when 'Ш' + lookahead_upcase 'SH' + when 'Щ' + lookahead_upcase 'SHCH' + when 'г' + behind =~ /[зЗ]/ ? 'gh' : 'h' + when 'Г' + behind =~ /[зЗ]/ ? lookahead_upcase('GH') : 'H' + when 'є' + letter?(behind) ? 'ie' : 'ye' + when 'Є' + letter?(behind) ? lookahead_upcase('IE') : lookahead_upcase('YE') + when 'ї' + letter?(behind) ? 'i' : 'yi' + when 'Ї' + letter?(behind) ? 'I' : lookahead_upcase('YI') + when 'й' + letter?(behind) ? 'i' : 'y' + when 'Й' + letter?(behind) ? 'I' : 'Y' + when 'ю' + letter?(behind) ? 'iu' : 'yu' + when 'Ю' + letter?(behind) ? lookahead_upcase('IU') : lookahead_upcase('YU') + when 'я' + letter?(behind) ? 'ia' : 'ya' + when 'Я' + letter?(behind) ? lookahead_upcase('IA') : lookahead_upcase('YA') + when "'" + # remove apostrophe inside a word + letter?(behind) && letter?(ahead) ? '' : "'" + else + straight_lookup[char] || char + end + end + end + end + + private + + def behind + @pre_match && @pre_match[-1] + end + + def ahead + @post_match && @post_match[0] + end + + def downcased?(symbol) + symbol =~ downcased_regexp + end + + def downcased_regexp + @downcased_regexp ||= /[а-яґєії]/ + end + + # apostrophe can be inside a word + def letter?(symbol) + symbol =~ letter_regexp + end + + def letter_regexp + @letter_regexp ||= /[а-яґєіїА-ЯҐЄІЇ'’]/ + end + + def lookahead_upcase(word) + downcased?(ahead) ? word.capitalize : word.upcase + end + + def straight_lookup + @straight_lookup ||= { + 'а'=>'a','б'=>'b','в'=>'v','ґ'=>'g','д'=>'d','е'=>'e','ж'=>'zh', + 'з'=>'z','и'=>'y','і'=>'i','к'=>'k','л'=>'l','м'=>'m','н'=>'n','о'=>'o', + 'п'=>'p','р'=>'r','с'=>'s','т'=>'t','у'=>'u','ф'=>'f','х'=>'kh','ц'=>'ts', + 'ч'=>'ch','ш'=>'sh','щ'=>'shch','ь'=>'','’'=>'', + 'А'=>'A','Б'=>'B','В'=>'V','Ґ'=>'G','Д'=>'D','Е'=>'E', + 'З'=>'Z','И'=>'Y','І'=>'I','К'=>'K','Л'=>'L','М'=>'M','Н'=>'N','О'=>'O', + 'П'=>'P','Р'=>'R','С'=>'S','Т'=>'T','У'=>'U','Ф'=>'F','Ь'=>'' + } + end + end + end + + # (c) Yaroslav Markin, Julian "julik" Tarkhanov and Co + # https://github.com/yaroslav/russian/blob/master/lib/russian/transliteration.rb + module Russian + class << self + def rule + lambda do |string| + next '' unless string + + chars = string.scan(%r{#{multi_keys.join '|'}|\w|.}) + + result = +"" + + chars.each_with_index do |char, index| + if upper.has_key?(char) && lower.has_key?(chars[index+1]) + # combined case + result << upper[char].downcase.capitalize + elsif upper.has_key?(char) + result << upper[char] + elsif lower.has_key?(char) + result << lower[char] + else + result << char + end + end + + result + end + end + + private + + # use instance variables instead of constants to prevent warnings + # on re-evaling after I18n.reload! + + def upper + @upper ||= begin + upper_single = { + "Ґ"=>"G","Ё"=>"YO","Є"=>"E","Ї"=>"YI","І"=>"I", + "А"=>"A","Б"=>"B","В"=>"V","Г"=>"G", + "Д"=>"D","Е"=>"E","Ж"=>"ZH","З"=>"Z","И"=>"I", + "Й"=>"Y","К"=>"K","Л"=>"L","М"=>"M","Н"=>"N", + "О"=>"O","П"=>"P","Р"=>"R","С"=>"S","Т"=>"T", + "У"=>"U","Ф"=>"F","Х"=>"H","Ц"=>"TS","Ч"=>"CH", + "Ш"=>"SH","Щ"=>"SCH","Ъ"=>"'","Ы"=>"Y","Ь"=>"", + "Э"=>"E","Ю"=>"YU","Я"=>"YA", + } + + (upper_single.merge(upper_multi)).freeze + end + end + + def lower + @lower ||= begin + lower_single = { + "і"=>"i","ґ"=>"g","ё"=>"yo","№"=>"#","є"=>"e", + "ї"=>"yi","а"=>"a","б"=>"b", + "в"=>"v","г"=>"g","д"=>"d","е"=>"e","ж"=>"zh", + "з"=>"z","и"=>"i","й"=>"y","к"=>"k","л"=>"l", + "м"=>"m","н"=>"n","о"=>"o","п"=>"p","р"=>"r", + "с"=>"s","т"=>"t","у"=>"u","ф"=>"f","х"=>"h", + "ц"=>"ts","ч"=>"ch","ш"=>"sh","щ"=>"sch","ъ"=>"'", + "ы"=>"y","ь"=>"","э"=>"e","ю"=>"yu","я"=>"ya", + } + + (lower_single.merge(lower_multi)).freeze + end + end + + def upper_multi + @upper_multi ||= { "ЬЕ"=>"IE", "ЬЁ"=>"IE" } + end + + def lower_multi + @lower_multi ||= { "ье"=>"ie", "ьё"=>"ie" } + end + + def multi_keys + @multi_keys ||= (lower_multi.merge(upper_multi)).keys.sort_by {|s| s.length}.reverse.freeze + end + end + end + end +end + diff --git a/rails/pluralization/ar.rb b/rails/pluralization/ar.rb index 2ca1a4283..8dd90137d 100644 --- a/rails/pluralization/ar.rb +++ b/rails/pluralization/ar.rb @@ -1,30 +1,4 @@ -module RailsI18n - module Pluralization - module Arabic - def self.rule - lambda do |n| - return :other unless n.is_a?(Numeric) - - mod100 = n % 100 - - if n == 0 - :zero - elsif n == 1 - :one - elsif n == 2 - :two - elsif (3..10).to_a.include?(mod100) - :few - elsif (11..99).to_a.include?(mod100) - :many - else - :other - end - end - end - end - end -end +require 'rails_i18n/pluralization' { :ar => { :'i18n' => { diff --git a/rails/pluralization/gd.rb b/rails/pluralization/gd.rb index 25648ebcd..bda3e569e 100644 --- a/rails/pluralization/gd.rb +++ b/rails/pluralization/gd.rb @@ -1,26 +1,4 @@ -module RailsI18n - module Pluralization - module ScottishGaelic - def self.rule - lambda do |n| - return :other unless n.is_a?(Numeric) - - floorn = n.floor - - if floorn == 1 || floorn == 11 - :one - elsif floorn == 2 || floorn == 12 - :two - elsif (3..19).member?(floorn) - :few - else - :other - end - end - end - end - end -end +require 'rails_i18n/pluralization' { :gd => { :'i18n' => { diff --git a/rails/pluralization/hsb.rb b/rails/pluralization/hsb.rb index 80447ccdc..351ba5713 100644 --- a/rails/pluralization/hsb.rb +++ b/rails/pluralization/hsb.rb @@ -1,23 +1,4 @@ -module RailsI18n - module Pluralization - module UpperSorbian - def self.rule - lambda do |n| - return :other unless n.is_a?(Numeric) - - mod100 = n % 100 - - case mod100 - when 1 then :one - when 2 then :two - when 3, 4 then :few - else :other - end - end - end - end - end -end +require 'rails_i18n/pluralization' { :hsb => { :'i18n' => { diff --git a/rails/pluralization/lt.rb b/rails/pluralization/lt.rb index 3b2038c46..5bd48ceb6 100644 --- a/rails/pluralization/lt.rb +++ b/rails/pluralization/lt.rb @@ -1,25 +1,4 @@ -module RailsI18n - module Pluralization - module Lithuanian - def self.rule - lambda do |n| - return :other unless n.is_a?(Numeric) - - mod10 = n % 10 - mod100 = n % 100 - - if mod10 == 1 && !(11..19).to_a.include?(mod100) - :one - elsif (2..9).to_a.include?(mod10) && !(11..19).to_a.include?(mod100) - :few - else - :other - end - end - end - end - end -end +require 'rails_i18n/pluralization' { :lt => { :'i18n' => { diff --git a/rails/pluralization/lv.rb b/rails/pluralization/lv.rb index 0b2b02ac9..28201ad21 100644 --- a/rails/pluralization/lv.rb +++ b/rails/pluralization/lv.rb @@ -1,18 +1,4 @@ -module RailsI18n - module Pluralization - module Latvian - def self.rule - lambda do |n| - if n.is_a?(Numeric) && n % 10 == 1 && n % 100 != 11 - :one - else - :other - end - end - end - end - end -end +require 'rails_i18n/pluralization' { :lv => { :'i18n' => { diff --git a/rails/pluralization/mk.rb b/rails/pluralization/mk.rb index b3b45442b..2def0df7b 100644 --- a/rails/pluralization/mk.rb +++ b/rails/pluralization/mk.rb @@ -1,18 +1,4 @@ -module RailsI18n - module Pluralization - module Macedonian - def self.rule - lambda do |n| - if n.is_a?(Numeric) && n % 10 == 1 && n != 11 - :one - else - :other - end - end - end - end - end -end +require 'rails_i18n/pluralization' { :mk => { :'i18n' => { diff --git a/rails/pluralization/pl.rb b/rails/pluralization/pl.rb index be3ca855c..b692713a3 100644 --- a/rails/pluralization/pl.rb +++ b/rails/pluralization/pl.rb @@ -1,27 +1,4 @@ -module RailsI18n - module Pluralization - module Polish - def self.rule - lambda do |n| - return :other unless n.is_a?(Numeric) - - mod10 = n % 10 - mod100 = n % 100 - - if n == 1 - :one - elsif [2, 3, 4].include?(mod10) && ![12, 13, 14].include?(mod100) - :few - elsif [0, 1, 5, 6, 7, 8, 9].include?(mod10) || [12, 13, 14].include?(mod100) - :many - else - :other - end - end - end - end - end -end +require 'rails_i18n/pluralization' { :pl => { :'i18n' => { diff --git a/rails/pluralization/sl.rb b/rails/pluralization/sl.rb index a0ab87057..bba47eb08 100644 --- a/rails/pluralization/sl.rb +++ b/rails/pluralization/sl.rb @@ -1,21 +1,4 @@ -module RailsI18n - module Pluralization - module Slovenian - def self.rule - lambda do |n| - return :other unless n.is_a?(Numeric) - - case n % 100 - when 1 then :one - when 2 then :two - when 3, 4 then :few - else :other - end - end - end - end - end -end +require 'rails_i18n/pluralization' { :sl => { :'i18n' => { diff --git a/rails/transliteration/ru.rb b/rails/transliteration/ru.rb index 0f358b245..1d756faa5 100644 --- a/rails/transliteration/ru.rb +++ b/rails/transliteration/ru.rb @@ -1,91 +1,4 @@ -# encoding: utf-8 - -# (c) Yaroslav Markin, Julian "julik" Tarkhanov and Co -# https://github.com/yaroslav/russian/blob/master/lib/russian/transliteration.rb - -module RailsI18n - module Transliteration - module Russian - class << self - def rule - lambda do |string| - next '' unless string - - chars = string.scan(%r{#{multi_keys.join '|'}|\w|.}) - - result = +"" - - chars.each_with_index do |char, index| - if upper.has_key?(char) && lower.has_key?(chars[index+1]) - # combined case - result << upper[char].downcase.capitalize - elsif upper.has_key?(char) - result << upper[char] - elsif lower.has_key?(char) - result << lower[char] - else - result << char - end - end - - result - end - end - - private - - # use instance variables instead of constants to prevent warnings - # on re-evaling after I18n.reload! - - def upper - @upper ||= begin - upper_single = { - "Ґ"=>"G","Ё"=>"YO","Є"=>"E","Ї"=>"YI","І"=>"I", - "А"=>"A","Б"=>"B","В"=>"V","Г"=>"G", - "Д"=>"D","Е"=>"E","Ж"=>"ZH","З"=>"Z","И"=>"I", - "Й"=>"Y","К"=>"K","Л"=>"L","М"=>"M","Н"=>"N", - "О"=>"O","П"=>"P","Р"=>"R","С"=>"S","Т"=>"T", - "У"=>"U","Ф"=>"F","Х"=>"H","Ц"=>"TS","Ч"=>"CH", - "Ш"=>"SH","Щ"=>"SCH","Ъ"=>"'","Ы"=>"Y","Ь"=>"", - "Э"=>"E","Ю"=>"YU","Я"=>"YA", - } - - (upper_single.merge(upper_multi)).freeze - end - end - - def lower - @lower ||= begin - lower_single = { - "і"=>"i","ґ"=>"g","ё"=>"yo","№"=>"#","є"=>"e", - "ї"=>"yi","а"=>"a","б"=>"b", - "в"=>"v","г"=>"g","д"=>"d","е"=>"e","ж"=>"zh", - "з"=>"z","и"=>"i","й"=>"y","к"=>"k","л"=>"l", - "м"=>"m","н"=>"n","о"=>"o","п"=>"p","р"=>"r", - "с"=>"s","т"=>"t","у"=>"u","ф"=>"f","х"=>"h", - "ц"=>"ts","ч"=>"ch","ш"=>"sh","щ"=>"sch","ъ"=>"'", - "ы"=>"y","ь"=>"","э"=>"e","ю"=>"yu","я"=>"ya", - } - - (lower_single.merge(lower_multi)).freeze - end - end - - def upper_multi - @upper_multi ||= { "ЬЕ"=>"IE", "ЬЁ"=>"IE" } - end - - def lower_multi - @lower_multi ||= { "ье"=>"ie", "ьё"=>"ie" } - end - - def multi_keys - @multi_keys ||= (lower_multi.merge(upper_multi)).keys.sort_by {|s| s.length}.reverse.freeze - end - end - end - end -end +require 'rails_i18n/transliteration' { :ru => { :i18n => { diff --git a/rails/transliteration/uk.rb b/rails/transliteration/uk.rb index 34e27ff5a..183624b2b 100644 --- a/rails/transliteration/uk.rb +++ b/rails/transliteration/uk.rb @@ -1,111 +1,4 @@ -# encoding: utf-8 - -module RailsI18n - module Transliteration - module Ukrainian - class << self - def rule - lambda do |string| - next '' unless string - - string.gsub(/./) do |char| - # Regexp.last_match is local to the thread and method scope - # of the method that did the pattern match. - @pre_match, @post_match = $`, $' - - case char - when 'Ж' - lookahead_upcase 'ZH' - when 'Х' - lookahead_upcase 'KH' - when 'Ц' - lookahead_upcase 'TS' - when 'Ч' - lookahead_upcase 'CH' - when 'Ш' - lookahead_upcase 'SH' - when 'Щ' - lookahead_upcase 'SHCH' - when 'г' - behind =~ /[зЗ]/ ? 'gh' : 'h' - when 'Г' - behind =~ /[зЗ]/ ? lookahead_upcase('GH') : 'H' - when 'є' - letter?(behind) ? 'ie' : 'ye' - when 'Є' - letter?(behind) ? lookahead_upcase('IE') : lookahead_upcase('YE') - when 'ї' - letter?(behind) ? 'i' : 'yi' - when 'Ї' - letter?(behind) ? 'I' : lookahead_upcase('YI') - when 'й' - letter?(behind) ? 'i' : 'y' - when 'Й' - letter?(behind) ? 'I' : 'Y' - when 'ю' - letter?(behind) ? 'iu' : 'yu' - when 'Ю' - letter?(behind) ? lookahead_upcase('IU') : lookahead_upcase('YU') - when 'я' - letter?(behind) ? 'ia' : 'ya' - when 'Я' - letter?(behind) ? lookahead_upcase('IA') : lookahead_upcase('YA') - when "'" - # remove apostrophe inside a word - letter?(behind) && letter?(ahead) ? '' : "'" - else - straight_lookup[char] || char - end - end - end - end - - private - - def behind - @pre_match && @pre_match[-1] - end - - def ahead - @post_match && @post_match[0] - end - - def downcased?(symbol) - symbol =~ downcased_regexp - end - - def downcased_regexp - @downcased_regexp ||= /[а-яґєії]/ - end - - # apostrophe can be inside a word - def letter?(symbol) - symbol =~ letter_regexp - end - - def letter_regexp - @letter_regexp ||= /[а-яґєіїА-ЯҐЄІЇ'’]/ - end - - def lookahead_upcase(word) - downcased?(ahead) ? word.capitalize : word.upcase - end - - def straight_lookup - @straight_lookup ||= { - 'а'=>'a','б'=>'b','в'=>'v','ґ'=>'g','д'=>'d','е'=>'e','ж'=>'zh', - 'з'=>'z','и'=>'y','і'=>'i','к'=>'k','л'=>'l','м'=>'m','н'=>'n','о'=>'o', - 'п'=>'p','р'=>'r','с'=>'s','т'=>'t','у'=>'u','ф'=>'f','х'=>'kh','ц'=>'ts', - 'ч'=>'ch','ш'=>'sh','щ'=>'shch','ь'=>'','’'=>'', - 'А'=>'A','Б'=>'B','В'=>'V','Ґ'=>'G','Д'=>'D','Е'=>'E', - 'З'=>'Z','И'=>'Y','І'=>'I','К'=>'K','Л'=>'L','М'=>'M','Н'=>'N','О'=>'O', - 'П'=>'P','Р'=>'R','С'=>'S','Т'=>'T','У'=>'U','Ф'=>'F','Ь'=>'' - } - end - end - end - end -end +require 'rails_i18n/transliteration' { :uk => { :i18n => {