Merb_babel

A plugin for the Merb framework that provides locales, languages, countries. (in a thread safe environment)

Purpose of Merb_babel

Merb_babel is primarily written to fulfill my personal needs. Instead of porting my http://github.com/mattetti/globalite plugin over, I decided to re write it from scratch learning from my mistakes.

Goals:

  • simplicity
  • speed

My first and simple objective is to get Merb to work in Simplified and Traditional Chinese + switch from one to the other.

Also, as of today, I'm not planning on supporting model localization since I believe it's easy to do, and in most cases it's too specific to use a plugin. (but other plugins offer that for you anyway ;) )

One of the objectives is that people can add Merb_babel to their project and use merb in a different language without worrying about internationalization/localization. I hope to keep merb helpers and other plugins (merb_activerecord / merb_datamapper / merb_sequel) localized so someone can define his app's locale/language/country and Merb will talk his language right away.

Before you go further, you might want to read this explanation about i18n/l10n

Usage

In your application controller add:

before :set_locale

and access the user locale using @controller.locale (or simply #locale in the controller) If a locale is set, you can also access @controller.language and @controller.country (same thing, you can use #language or #country from within your controller scope)

The locale is stored in request.env[:locale]

At the moment you have 3 ways of setting up a locale:

  • default way in the config settings (that you can overwrite in your init.rb file )

    Merb::Plugins.config[:Merb_babel] = { :default_locale => 'en-US', :default_language => 'en', :default_country => 'US' }

  • per request basis, by sending a param called locale (language, and country will set their own values)

  • store the locale in the session

  • use routes

Babel doesn't support http header lookup yet.

Set locale in your routes

r.match(/\/?(en\-US|en\-UK|es\-ES|es\-AR)?/).to(:locale => "[1]") do |l|
  l.match("/articles/:action/:id").to(:controller => "articles")
end

What if you don't need to use a full locale?

some people might not need to use the full locale, they just want to use one version of a language and the locale is an overkill. Don't worry, you can use the language instance variable.

before :set_language

All locale work is done in merb_babel/lib/merb_babel/m_locale.rb and tested in spec/merb_babel_spec.rb

Localization(L10n)

L10n is basically the adaptation of your product to a specific locale. In our case, we see L10n as the storing and retrieval of localized data. (for a locale or language)

Localizations are loaded from localization files.

Localization files are simple yaml files that get loaded in memory. By default Merb_babel will look in ./lang for localization files. The default location is defined in Merb::Plugins.config[:merb_babel][:localization_dirs] and can be overwritten. Also, you can add more folders to look for by calling:

add_localization_dir(path_with_more_localization_files)

Note: when you add a new localization directory, localizations gets reloaded. This needs to be done when Merb loads as I didn't add a mutex around that task yet.

Localizations are available in #localizations and are namespaced as follows:

localizations['en'][:right] => 'right'
localizations['en'][:left] => 'left'
localizations['en']['US'][:greeting] => 'Howdie'
localizations['en']['AU'][:greeting] => "Good'ay"

For that the localization files to be loaded properly, you need to follow some conventions:

  • you have to declare a merb localization language code pair: mloc_language_code: en where en represents the language code of the localization

  • All generic localization for a language should go under their own language file. Region/culture specific localizations have to go to their own files and will be used if the full locale is set.

  • A localization file is recognized as being locale specific if the mloc_country_code pair is set.

  • ONLY localizations/translations specific to a locale should be written in a locale file.

  • Recommended: set the mloc_language_name pair so you list the available languages in their own language.

  • look at examples in spec/lang

All the Localization(L10n) work is done in merb_babel/lib/merb_abel/m_l10n.rb and tested in spec/m_l10n_spec.rb

Internationalization(I18n)

I18n enables easy localization of your product. That's what the developer/designer user to make their data localizable.

At the moment, only strings can be localized/translated.

In your controller, or view simply do:

translate(:localization_key)

You might prefer a shorter version so here are some aliases for you to use:

babelize(:translation_key)

or t(:translation_key)
or _(:translation_key)

The translation will use the full locale (language and country) if set and available, otherwise the language translation will be displayed.

Params

You can pass a hash of parameters after the translation key. For instance:

t(:greetings, :language => 'fr')

Would lookup the French translation for the greetings key and return 'Salut'

You can also pass the country code to use the full locale.

t(:greetings, :language => 'en', :country => 'AU')

would lookup the Australian English translation for the greetings key and return "G'day"

Other plugins you might want to look at: