Your SlideShare is downloading. ×
The Ruby On Rails I18n Core Api
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

The Ruby On Rails I18n Core Api

3,400

Published on

My presentation on I18n during Ruby India Conference 2010, Bangalore, India

My presentation on I18n during Ruby India Conference 2010, Bangalore, India

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,400
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
11
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • Need to understand.
  • Transcript

    • 1. The Ruby on Rails I18n Core API PRESENTED BY -Neeraj Kumar
    • 2. Introduction
      • English – Default Language.
      • Gettext
      • Tough Task – transform your ROR App into its regional language & providing a tool to solve all problems at once.
    • 3.
      • Provides easy-to-use and extensible framework.
      • Translating
      • - to a single custom language other than English.
      • - for providing multi-language support.
    • 4.
      • To abstract all strings and other locale specific bits (such as date or currency formats) out of your application. The process of “localization” means to provide translations and localized formats for these bits.
      • Sven Fuchs
      • Shipped with rails (started with rails-2.2)
    • 5.
      • In the process of internationalizing:
        • Ensure you have support for i18n
        • Tell Rails where to find locale dictionaries
        • Tell Rails how to set, preserve and switch locale
    • 6. Setup for RoR App
      • Configure the I18n Module
        • .rb and .yml + translations load path , automatically.
        • translations load path ( I18n.load_path ) - will be loaded automatically and available in your application.
    • 7.
        • environment.rb - instructions to customize the locale directory and default locale.e.g.
      • # config.i18n.load_path << Dir[File.join(RAILS_ROOT, 'my', 'locales', '*.{rb,yml}')]
      • # config.i18n.default_locale = :de
      en: hello: &quot;Hello world&quot;
    • 8.
      • Setting and Passing the Locale
      • - For more locales - to set and pass the locale between requests.
      • - Don't use session or cookies to store the chosen locale.
    • 9. before_filter :set_locale def set_locale # if params[:locale] is nil then I18n.default_locale will be used I18n .locale = params[ :locale ] end - URL : http://example.com/books?locale=pt - will load Portuguese localization.
    • 10.
      • Locale setting from the URL Params
      • - link_to( books_url(:locale => I18n.locale)) - tedious and probably impossible.
      • - For 'centralizing dynamic decisions about the URLs' in its ApplicationController#default_url_options.
    • 11. # app/controllers/application_controller.rb def default_url_options (options = {}) logger.debug “default_url_options is passed options: #{options.inspect} ” { :locale => I18n .locale} end - Every helper method dependent on url_for automatically include the locale in the query string .
    • 12. # config/routes.rb map.resources :books , :path_prefix => '/:locale' # => www.example.com/nl/books map.root '/:locale' , :controller => “dashboard”
    • 13. - Drawback of default_url_options implementation pass the :id option, e.g. link_to 'show', book_url(:id => book)
    • 14.
      • Locale setting from the Domain Name
      • - advantages
            • Locale, an obvious part of URL
            • Trivial to implement
            • Intuitively grasp the language of content before loading
            • Search engines like content in different languages at different domains.
    • 15. before_filter :set_locale def set_locale I18n .locale = extract_locale_from_uri end
    • 16. def extract_locale_from_tld parsed_locale = request.host.split( '.' ).last I18n .available_locales.include?(parsed_locale.to_sym) ? parsed_locale : nil end - parsed_locale = request.host.split('.').first to set the locale from subdomain.
    • 17.
      • Locale setting from the Client Supplied Information
      • - information can come from
        • Users preferred language (set in their browser)
        • Users geographical location inferred from IP
        • By choosing locale in your application interface and saving to the profile.
    • 18. def set_locale logger.debug = “* Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}” I18n .locale = extract_locale_from_accept_language_header end
    • 19. def extract_locale_from_accept_language_header request.env[ 'HTTP_ACCEPT_LANGUAGE' ].scan( /^[a-z]{2}/ ).first end - Using GeoIP (or similar) Database – GeoIP Lite Country - User Profile
    • 20. en: activerecord: models: user: foo admin: bar attributes: user: login: “Handle” # => will translate User attribute “login” as “Handle”
      • Active Record Model Translations
    • 21. en: activerecord: errors: messages: blank: “can not has nothing” # => #<User id:nil, etc> # => u.valid? # => false # => u.errors.on(:name) # => “can not has nothing”
        • Error Messages Scope - Active Record Validation Error Messages Translation
    • 22.
      • Active Record will look up this key in the namespaces
        • activerecord.errors.models.[model_name].attributes.[attribute_name]
        • activerecord.errors.models.[model_name]
        • activerecord.errors.messages
    • 23. en: activerecord: errors: messages: already_registered: “u already is {{model}}” # => u.errors.on(:email) # => “u already is foo”
      • Error Message Interpolation
        • Count can be used for Pluralization
    • 24.
      • Translation for the Active Record error_messages_for Helper
      en: activerecord: errors: template: header: one: “1 error prohibted this {{model}} from being saved” other: “{{count}} errors prohibted this {{model}} from being saved” body: “There were problems with the following fields:”
    • 25. Anatomy of Gem i18n i18n backend core_ext helpers locales backend exceptions gettext helpers locale i18n version locale gettext fallbacks tag
    • 26. active_record Interpolation compiler Interpolation compiler Interpolation compiler Interpolation compiler Interpolation compiler Interpolation compiler Interpolation compiler fast gettext helpers Interpolation compiler links metadata simple active_record base cache cascader chain cldr fallbacks pluralization missing translation store_procs backend
    • 27. i18n.rb
      • get and set methods for default_locale.
      def default_locale(locale) @@default_locale = locale.to_sym rescue nil end
      • Get method for locale - either default_locale or locale in Thread.current hash.
    • 28. i18n.rb
      • Set method for locale - set the locale in Thread.current
      • Returns the current backend.
      def backend @@backend ||= Backend::Simple .new end
      • Set method for current backend.
    • 29. simple.rb
      • Makes easier to extend the Simple backend's behaviour by including modules e.g. I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization).
      module I18n module Backend class Simple include Base end end end
    • 30. i18n.rb def available_locales @@available_locales ||= backend.available_locales end
    • 31. I18n.rb
      • Default scope separator method (i.e default_separator)
        • set your separator
        • return the separator.
      • Default is '.'
    • 32. I18n.rb
      • Exception handler method (i.e. exception_handler)
        • set your exception handler
        • return the current exception handler.
      • Default is :default_exception_handler private method.
    • 33. I18n.rb def default_exception_handler (exception, locale, key, options) return exception.message if MissingTranslationData === exception raise exception end
    • 34. I18n.rb
      • load_path=(load_path) method - set load path instance.
      • load_path method
        • *.rb and contain plain Ruby Hashes.
        • *.yml and contain YAML data.
    • 35. I18n.rb
      • Class method config returns I18n configuration object
      def config Thread .current[ :i18n_config ] ||= I18n::Config .new end
      • method config=(value) sets I18n configuration object.
    • 36. I18n.rb
      • Method to reload the translations.
      • Main method translate and localize
      • I18n.t :message I18n.t 'message'
    • 37. I18n.rb
      • Translation method – scope options, interpolation, pluralization, defaults
      • :scope option – one or many keys - scope for a translation key
      I18n .t :invalid , :scope => [ :active_record , :error_messages ] # => I18n.translation :invalid :active_record.error_messages.invalid
    • 38. I18n.rb
      • Interpolation
      I18n. t :foo , :bar => 'baz' #=> 'foo baz' I18n. t :foo , :count => 1 #=> 'foo' I18n. t :foo , :count => 0 #=> 'foos' I18n. t :foo , :count => 2 #=> 'foos'
      • Pluralization
      • Defaults
      I18n. t :foo , :default => 'bar'
    • 39. I18n.rb
      • def translate (&args)
        • options = args.pop if args.last.is_a?( Hash )
        • key = args.shift
        • locale = options && options.delete( :locale ) || config.locale
        • raises = options && options.delete( :raise )
        • config.backend.translate(locale, key, options || {})
        • rescue I18n::ArgumentError => exception
        • raise exception if raises
        • handle_exception(exception, locale, key, options)
      • end
      • alias :t :translate
    • 40. I18n.rb
      • def localize (object, options = {})
        • locale = options.delete( :locale ) || config.locale
        • format = options.delete( :format ) || :default
        • config.backend.localize(locale, object, format, options)
      • end
      • alias :l :localize
    • 41. base.rb
      • load_translations method - accepts list of paths of translation files.
      def load_translations (*filenames) filenames.each { |filename| load_file(filename) } end
    • 42. base.rb
      • def load_file (filename)
        • type = File .extname(filename).tr('.', '').downcase
        • raise UnknownFileType .new(type, filename) unless respond_to?(: ”load_#(type)” )
        • data = send(: ”load_#(type)” , filename)
        • data.each { |locale, d| merge_translation(locale, d) }
      • end
    • 43. base.rb def store_translations (locale, data, options = {}) merge_translations(locale, data, options) end
    • 44.
      • def merge_translations (locale, data, options = {})
        • locale = locale.to_sym
        • translations[locale] ||= {}
        • separator = options[ :separator ] || I18n .default_separator
        • data = unwind_keys(data, separator)
        • data = deep_symbolized_keys(data)
        • merger = proc do |key, v1, v2|
        • Hash === v1 && Hash === v2 ?
        • v1.merge(v2, &merger) : (v2 || v1)
        • end
        • translations[locale].merge!(data, &merger)
      • end
      base.rb
    • 45. base.rb def translate (locale, key, options = {}) raise InvalidLocale .new(locale) unless locale return key.map { |k| translate(locale, k, options) } if key.is_a?( Array ) if options.empty? entry = resolve(locale, key, lookup(locale, key), options) raise ( I18n::MissingTranslationData .new(locale, key, options)) if entry.nil?
    • 46. else count, scope, default = options.values_at( :count , :scope , :default ) values = options.reject { |name, value| RESERVED_KEYS .include?(name) } entry = lookup(locale, key, scope, options) entry = entry.nil? && default ? default(locale, key, default, options) : resolve(locale, key, entry, options) base.rb
    • 47. raise ( I18n::MissingTranslationData .new(locale, key, options)) if entry.nil? e ntry = pluralize(locale, entry, count) if count entry = interpolate(locale, entry, values) if values end entry end base.rb
    • 48. base.rb
      • look_up method
        • looks up the translation from the translations hash.
        • Splits keys or scopes containing dots into multiple keys e.g. currency.format - %w(currency format).
    • 49. base.rb
      • localize method
      case match when '%a' then I18n . t(: &quot;date.abbr_day_names” , :locale => locale, :format => format)[object.wday] when '%A' then I18n .t(: &quot;date.day_names” , :locale => locale, :format => format)[object.wday] when '%b' then I18n .t(: &quot;date.abbr_month_names&quot; , :locale => locale, :format => format)[object.mon]
    • 50. when '%B' then I18n.t(: &quot;date.month_names&quot; , :locale => locale, :format => format)[object.mon] when '%p' then I18n.t(: &quot;time.#{object.hour < 12 ? :am : :pm}&quot; , :locale => locale, :format => format) if object.respond_to? :hour end base.rb
    • 51. Customization
      • Different Backends
        • I18n::Backend::Simple
            • shipped with Active Support of vendor directory, work for english or similar languages.
            • capable of reading translations but cannot dynamically store them to any format.
    • 52. MissingTranslationData # no translation was found for the requested key InvalidLocale # the locale set to I18n.locale is invalid (e.g. nil)
      • Different Exception Handlers
    • 53. - customization – e.g. the default exception handling does not allow to catch missing translation during automated test easily .
    • 54.
        • I18n
            • own backend
            • makes easy to exchange the Simple backend implementation with that to fits better with your need.
      I18n .backend = Globalize :: Backend :: Static .new
    • 55. module I18n def just_raise_that_exception (*args) raise args.first end end I18n .exception_handler = :just_raise_that_exception
    • 56. References
      • http://guides.rails.info/i18n.html
      • http://rails-i18n.org/wiki
      • http://iain.nl/2008/09/translating-activerecord/
      • http://github.com/svenfuchs/rails-i18n
      • http://rails-i18n.org/wiki/wikipages/i18n-rails-guide
      • http://www.artweb-design.de/2008/7/18/the-ruby-on-rails-i18n-core-api
    • 57.
      • Questions?
    • 58.
      • Thank You!

    ×