Hello, I have never posted here, neither contributed to any open source project. So I am not sure how to go about this. This is a proposal and a question at the same time. Trying to know if what is my head is valuable for Rails. It is just a tiny change.
In the Rails Internationalisation guide <http://guides.rubyonrails.org/i18n.html#using-different-exception-handlers> it shows how to set up a customer exception handler for I18n. In the documentation is explained that Rails TranslationHelper will not use this custom exception handler. *Another example where the default behavior is less desirable is the Rails TranslationHelper which provides the method #t (as well as #translate). When a MissingTranslationData exception occurs in this context, the helper wraps the message into a span with the CSS class translation_missing.* I think it would be useful to be able to have a I18n custom exception handler even for the Rails Views and pass it the default translations. It would allow to raise exceptions locally while failing silently in production and at the same time returning the default translation. I show this in the following Exception handler: module I18n class JustRaiseExceptionHandler < ExceptionHandler def call(exception, locale, key, options) raise exception if Rails.env.development? Rails.logger.error "#{exception} #{locale} #{key}" options[:default_translation] end end end I have added two lines to the ActionView::Helpers::TranslationHelper#translate that would allow this behaviour with a given configuration. The only change is inside the rescue clause, after line 91 in original implementation <https://github.com/rails/rails/blob/master/actionview/lib/action_view/helpers/translation_helper.rb#L91> . Do you think this is valuable for Rails? Regards, David. def translate(key, options = {}) options = options.dup has_default = options.has_key?(:default) remaining_defaults = Array(options.delete(:default)).compact if has_default && !remaining_defaults.first.kind_of?(Symbol) options[:default] = remaining_defaults end # If the user has explicitly decided to NOT raise errors, pass that option to I18n. # Otherwise, tell I18n to raise an exception, which we rescue further in this method. # Note: `raise_error` refers to us re-raising the error in this method. I18n is forced to raise by default. if options[:raise] == false || (options.key?(:rescue_format) && options[:rescue_format].nil?) raise_error = false i18n_raise = false else raise_error = options[:raise] || options[:rescue_format] || ActionView::Base.raise_on_missing_translations i18n_raise = true end if html_safe_translation_key?(key) html_safe_options = options.dup options.except(*I18n::RESERVED_KEYS).each do |name, value| unless name == :count && value.is_a?(Numeric) html_safe_options[name] = ERB::Util.html_escape(value.to_s) end end translation = I18n.translate(scope_key_by_partial(key), html_safe_options.merge(raise: i18n_raise)) translation.respond_to?(:html_safe) ? translation.html_safe : translation else I18n.translate(scope_key_by_partial(key), options.merge(raise: i18n_raise)) end rescue I18n::MissingTranslationData => e if remaining_defaults.present? translate remaining_defaults.shift, options.merge(default: remaining_defaults) else raise e if raise_error keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope]) default_translation = content_tag('span', keys.last.to_s.titleize, :class => 'translation_missing', :title => "translation missing: #{keys.join('.')}") if custom_exception_handler? I18n.exception_handler.call(e, e.locale, e.key, {default_translation: default_translation}) else default_translation end end end alias :t :translate private def custom_exception_handler? true # ActionView::Base.use_i18n_exception_handler end -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/rubyonrails-core. For more options, visit https://groups.google.com/d/optout.
