1414
1515I18n . enforce_available_locales = true
1616
17+ I18nliner . infer_interpolation_values = false
18+
1719if ENV [ 'LOLCALIZE' ]
1820 require 'i18n_tasks'
1921 I18n . send :extend , I18nTasks ::Lolcalize
@@ -85,116 +87,53 @@ def blabel(method, text = nil, options = {})
8587 end
8688end
8789
88- I18n . class_eval do
89- class << self
90- attr_writer :localizer
91-
92- include ::ActionView ::Helpers ::TextHelper
93- # if one of the interpolated values is a SafeBuffer (e.g. the result of a
94- # link_to call) or the string itself is, we don't want anything to get
95- # double-escaped when output in the view (since string is not html_safe).
96- # so we escape anything that's not safe prior to interpolation, and make
97- # sure we return a SafeBuffer.
98- def interpolate_hash_with_html_safety_awareness ( string , values )
99- if string . html_safe? || values . values . any? { |v | v . is_a? ( ActiveSupport ::SafeBuffer ) }
100- values . each_pair { |key , value | values [ key ] = ERB ::Util . h ( value ) unless value . html_safe? }
101- string = ERB ::Util . h ( string ) unless string . html_safe?
102- end
103- if string . is_a? ( ActiveSupport ::SafeBuffer ) && string . html_safe?
104- string . class . new ( interpolate_hash_without_html_safety_awareness ( string . to_str , values ) )
105- else
106- interpolate_hash_without_html_safety_awareness ( string , values )
107- end
108- end
109-
110- alias_method_chain :interpolate_hash , :html_safety_awareness
111-
112- # removes left padding from %e / %k / %l
113- def localize_with_whitespace_removal ( object , options = { } )
114- localize_without_whitespace_removal ( object , options ) . gsub ( /\s {2,}/ , ' ' ) . strip
115- end
116- alias_method_chain :localize , :whitespace_removal
117-
118- # Public: If a localizer has been set, use it to set the locale and then
119- # delete it.
120- #
121- # Returns nothing.
122- def set_locale_with_localizer
123- if @localizer
124- self . locale = @localizer . call
125- @localizer = nil
126- end
127- end
128-
129- def translate_with_default_and_count_magic ( key , *args )
130- set_locale_with_localizer
131-
132- default = args . shift if args . first . is_a? ( String ) || args . size > 1
133- options = args . shift || { }
134- options [ :default ] ||= if options [ :count ]
135- case default
136- when String
137- default =~ /\A [\w \- ]+\z / ? pluralize ( options [ :count ] , default ) : default
138- when Hash
139- case options [ :count ]
140- when 0
141- default [ :zero ]
142- when 1
143- default [ :one ]
144- end || default [ :other ]
145- else
146- default
147- end
148- else
149- default
150- end
151-
152- begin
153- result = translate_without_default_and_count_magic ( key . to_s . sub ( /\A #/ , '' ) , options )
154- rescue I18n ::MissingInterpolationArgument
155- # if we change an en default and its interpolation logic without
156- # changing its key, we might have broken translations during the
157- # window where we're waiting for updated translations. broken as in
158- # crashy, not just missing. if that's the case, just fall back to
159- # english, rather than asploding
160- raise if ( options [ :locale ] || I18n . locale ) == I18n . default_locale
161- return translate_with_default_and_count_magic ( key , options . merge ( locale : I18n . default_locale ) )
162- end
163-
164- # it's assumed that if you're using any wrappers, you're going
165- # for html output. so the result will be escaped before being
166- # wrapped, then the output tagged as html safe.
167- if wrapper = options [ :wrapper ]
168- result = I18n . apply_wrappers ( result , wrapper )
169- end
170-
171- result
90+ I18n . send ( :extend , Module . new {
91+ attr_writer :localizer
92+
93+ # Public: If a localizer has been set, use it to set the locale and then
94+ # delete it.
95+ #
96+ # Returns nothing.
97+ def set_locale_with_localizer
98+ if @localizer
99+ self . locale = @localizer . call
100+ @localizer = nil
172101 end
173- alias_method_chain :translate , :default_and_count_magic
174- alias :t :translate
175102 end
176103
177- WRAPPER_REGEXES = { }
178-
179- def self . apply_wrappers ( string , wrappers )
180- string = ERB ::Util . h ( string ) unless string . html_safe?
181- wrappers = { '*' => wrappers } unless wrappers . is_a? ( Hash )
182- wrappers . sort_by { |a | -a . first . length } . each do |sym , replace |
183- regex = ( WRAPPER_REGEXES [ sym ] ||= %r{#{ Regexp . escape ( sym ) } ([^#{ Regexp . escape ( sym ) } ]*)#{ Regexp . escape ( sym ) } } )
184- string = string . gsub ( regex , replace )
104+ def translate ( *args )
105+ set_locale_with_localizer
106+
107+ begin
108+ super
109+ rescue I18n ::MissingInterpolationArgument
110+ # if we change an en default and its interpolation logic without
111+ # changing its key, we might have broken translations during the
112+ # window where we're waiting for updated translations. broken as in
113+ # crashy, not just missing. if that's the case, just fall back to
114+ # english, rather than asploding
115+ key , options = I18nliner ::CallHelpers . infer_arguments ( args )
116+ raise if ( options [ :locale ] || locale ) == default_locale
117+ super ( key , options . merge ( locale : default_locale ) )
185118 end
186- string . html_safe
187119 end
120+ alias :t :translate
188121
189- def self . qualified_locale
190- I18n . backend . direct_lookup ( I18n . locale . to_s , "qualified_locale" ) || "en-US"
122+ def qualified_locale
123+ backend . direct_lookup ( locale . to_s , "qualified_locale" ) || "en-US"
191124 end
192- end
125+ } )
126+
127+ # see also corresponding extractor logic in
128+ # i18n_extraction/i18nliner_extensions
129+ require "i18n_extraction/i18nliner_scope_extensions"
193130
194131ActionView ::Template . class_eval do
195132 def render_with_i18n_scope ( view , *args , &block )
196133 old_i18n_scope = view . i18n_scope
197- view . i18n_scope = @virtual_path . gsub ( /\/ _?/ , '.' ) if @virtual_path
134+ if @virtual_path
135+ view . i18n_scope = I18nliner ::Scope . new ( @virtual_path . gsub ( /\/ _?/ , '.' ) )
136+ end
198137 render_without_i18n_scope ( view , *args , &block )
199138 ensure
200139 view . i18n_scope = old_i18n_scope
@@ -204,51 +143,27 @@ def render_with_i18n_scope(view, *args, &block)
204143
205144ActionView ::Base . class_eval do
206145 attr_accessor :i18n_scope
207-
208- # can accept either translate(key, default: "default text", option: ...) or
209- # translate(key, "default text", option: ...). when using the former (default
210- # in the options), it's treated as if prepended with a # anchor.
211- def translate ( key , *rest )
212- options = rest . extract_options!
213- default_in_options = options . has_key? ( :default )
214- default_in_args = !rest . empty?
215- raise ArgumentError , "wrong arity" if rest . size > 1
216- raise ArgumentError , "didn't provide default in args or options" if !default_in_args && !default_in_options
217- raise ArgumentError , "can't provide default in both args and options" if default_in_args && default_in_options
218- default = default_in_options ? options [ :default ] : rest . first
219- key = key . to_s
220- key = "#{ i18n_scope } .#{ key } " unless default_in_options || key . sub! ( /\A #/ , '' )
221- I18n . translate ( key , default , options )
222- end
223- alias :t :translate
224146end
225147
226148ActionController ::Base . class_eval do
227- def translate ( key , default , options = { } )
228- key = key . to_s
229- key = "#{ controller_name } .#{ key } " unless key . sub! ( /\A #/ , '' )
230- I18n . translate ( key , default , options )
149+ def i18n_scope
150+ @i18n_scope ||= I18nliner ::Scope . new ( controller_path . tr ( '/' , '.' ) )
231151 end
232- alias :t :translate
233152end
234153
235154ActiveRecord ::Base . class_eval do
236155 include I18nUtilities
237156 extend I18nUtilities
238157
239- def translate ( key , default , options = { } )
240- self . class . translate ( key , default , options )
158+ def i18n_scope
159+ self . class . i18n_scope
241160 end
242- alias :t :translate
243161
244- class << self
245- def translate ( key , default , options = { } )
246- key = key . to_s
247- key = "#{ name . underscore } .#{ key } " unless key . sub! ( /\A #/ , '' )
248- I18n . translate ( key , default , options )
249- end
250- alias :t :translate
162+ def self . i18n_scope
163+ @i18n_scope ||= I18nliner ::Scope . new ( self . class . name . underscore )
164+ end
251165
166+ class << self
252167 # so that we don't load up the locales until we need them
253168 LOCALE_LIST = [ ]
254169 def LOCALE_LIST . include? ( item )
@@ -273,10 +188,15 @@ def validates_locale(*args)
273188end
274189
275190ActionMailer ::Base . class_eval do
191+ def i18n_scope
192+ @i18n_scope ||= I18nliner ::Scope . new ( "#{ mailer_name } .#{ action_name } " )
193+ end
194+
276195 def translate ( key , default , options = { } )
277- key = key . to_s
278- key = "#{ mailer_name } .#{ action_name } .#{ key } " unless key . sub! ( /\A #/ , '' )
279- I18n . translate ( key , default , options )
196+ key , options = I18nliner ::CallHelpers . infer_arguments ( args )
197+ options = inferpolate ( options ) if I18nliner . infer_interpolation_values
198+ options [ :i18n_scope ] = i18n_scope
199+ I18n . translate ( key , options )
280200 end
281201 alias :t :translate
282202end
0 commit comments