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"