Friday, April 5, 2013

Using Rails’ New I18n Support in Real Life: Part the Third

December 15th, 2008 By: Daniel

What happens when you add a new string to your default locale file and forget about the other languages? Well, by default it’ll raise a MissingTranslationData and your users will see an ugly string the likes of “es-MX, marketing_interface, index, title“. Wouldn’t it be better to at least try and default to English? My guess is that most people would prefer to see the message in another language than some cryptic error message. And while we’re wishing, don’t you think the localize method shouldn’t die a noisy death when you happen to pass it a nil?
My solution? A custom I18n backend. I simply copy/pasted the code from the default “Simple” backend, tweaked a few lines and I was good to go!
# In some file that gets sourced on startup, like maybe in your config/initializers directory
module I18n
  module Backend
    class Moki < Simple
      def translate(locale, key, options = {})
        raise if locale.nil?
        return { |k| translate(locale, k, options) } if key.is_a? Array
        reserved = :scope, :default
        count, scope, default = options.values_at(:count, *reserved)
        values = options.reject { |name, value| reserved.include?(name) }
        entry = lookup(locale, key, scope)
        if entry.nil?
          entry = default(locale, default, options)
          entry ||= lookup(I18n.default_locale, key, scope)
          raise(, key, options)) if entry.nil?
        entry = pluralize(locale, entry, count)
        entry = interpolate(locale, entry, values)
      def localize(locale, object, format = :default)
        return nil if object.nil?
        raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime)
        type = object.respond_to?(:sec) ? 'time' : 'date'
        formats = translate(locale, "#{type}.formats")
        format = formats[format.to_sym] if formats && formats[format.to_sym]
        format = format.to_s.dup
        format.gsub!(/%a/, translate(locale, "date.abbr_day_names")[object.wday])
        format.gsub!(/%A/, translate(locale, "date.day_names")[object.wday])
        format.gsub!(/%b/, translate(locale, "date.abbr_month_names")[object.mon])
        format.gsub!(/%B/, translate(locale, "date.month_names")[object.mon])
        format.gsub!(/%p/, translate(locale, "time.#{object.hour < 12 ? :am : :pm}")) if object.respond_to? :hour
I18n.backend =

No comments:

Post a Comment