R18n

R18n is a i18n tool to translate your Ruby application in several languages.

Use sinatra-r18n or teamon’s merb_i18n to localize Web applications and r18n-desktop to localize desktop application.

Features

  • It has special support for countries with two official languages. If there isn’t translation in user locale, it will be found in locales, which user may know (not only in default locale). For example, many people in Belarus can understand Russian, and locale has information about it.

  • It can format numbers and time to the rules of the user locale, translate month and week days name and give other locale information.

  • It has translation for commons words, like “OK”, “Cancel”, etc.

  • It storage translation in rich YAML format. You can put procedures and pluralization (“1 comment”, “5 comments”) or create you own filters.

  • It can translate Web and desktop applications.

Usage

Translation

Translation files use YAML format and has name like en.yml (English) or en-us.yml (USA English dialect) with language/country code (RFC 3066).

In translation you can use:

  • Strings

    robot: This is robot
    percent: "Percent sign (%)"
    
  • Numbers

    number: 123
    float: 12.45
    
  • Pluralizable messages

    robots: !!pl
      0: No robots
      1: One robot
      n: %1 robots
    
  • Filters

    filtered: !!custom_type
      This content will be processed by filter
    

To get translated string use method with key name or square brackets [] for keys, which is same with Object methods (class, inspect, etc):

i18n.robot    #=> "This is robot"
i18n["robot"] #=> "This is robot"

Translation may be hierarchical:

i18n.post.add       #=> "Add post"
i18n['post']['add'] #=> "Add post"

If locale willn’t be found in user locale R18n will search it in they sublocales or in another locale, which user know:

i18n.no.in.english #=> "В английском нет"

Translated string has locale method and you can get it locale (Locale instance or code string if locale is’t supported in R18n):

i18n.no.in.english.locale #=> Locale ru (Русский)

You can replace some parameters in translated string by put it as arguments:

name: "My name is %1"

i18n.name('John') #=> "My name is John"

Pluralizable messages get item count from first argument:

i18n.robots(0)  #=> "No robots"
i18n.robots(1)  #=> "One robot"
i18n.robots(50) #=> "50 robots"

If there isn’t pluralization for some number, translation will be use ‘n’. If there isn’t locale file for translation, it will be use English pluralization rule (0, 1 and ‘n’).

R18n already has translation for common words for most supported locales. See base/ in dir in gem.

i18n.yes    #=> "Yes"
i18n.cancel #=> "Cancel"
i18n.delete #=> "Delete"

Filters

You can also add you own filter for translations: escape HTML entries, convert from Markdown syntax, etc.

R18n::Filters.add('custom_type', :filter_name) do |content, config, replace|
  content.gsub(' ', replace)
end
R18n::Filters.add('custom_type') do |content, config, replace|
  content + '!'
end

i18n.filtered('_') #=> "This_content_will_be_processed_by_filter!"

You can also add global filters for all translated strings:

R18n::Filters.add(String, :capitalize_ruby) do |content, config|
  content.gsub(/ruby/i) { |i| i.swapcase }
end

HTML Escape

R18n contain 2 filters to escape HTML entries: by YAML type and global. If you need to escape HTML in some translations, just set !!escape YAML type:

greater: !!escape
  1 < 2 is true

i18n.greater #=> "1 &lt; 2 is true"

If you develop web application and want to escape HTML in all translations, just activate global escape filter:

R18n::Filters.on(:global_escape_html)

If you enable global HTML escape, you may use !!html YAML type to disable escaping in some special value.

warning: !!html
  <b>Warning</b>

R18n::Filters.on(:global_escape_html)
i18n.warning #=> "<b>Warning</b>"

Markdown

To use Markdown in your translations you must install maruku gem:

hi: !!markdown
  **Hi**, people!

i18n.hi #=> "<p><strong>Hi</strong>, people!</p>"

Textile

To use Textile in your translations you must install RedCloth gem:

alarm: !!textile
  It will delete _all_ users!

i18n.alarm #=> "<p>It will delete <em>all</em> users!</p>"

Lambdas

You can use lambdas in your translations.

sum: !!proc |x, y| x + y

i18n.sum(1, 2) #=> 3

If it isn’t secure in your application (for example, user can change translations), you can disable it:

R18n::Filters.off(:procedure)

Localization

You can print number and float according to the rules of the user locale:

i18n.l -12000.5 #=> "−12,000.5"

Number and float formatters will also put real typographic minus and put non-break thin spaces (for locale, which use it as digit separator).

You can translate months and week days names in Time, Date and DateTime by strftime method:

i18n.l Time.now, '%B'  #=> "September"

R18n has some time formats for locales: :human, :full and :standard (by default):

i18n.l Time.now, :human #=> "now"
i18n.l Time.now, :full  #=> "August 9th, 2009 21:47"
i18n.l Time.now         #=> "08/09/2009 21:41"
i18n.l Time.now.to_date #=> "08/09/2009"

Model

You can add i18n support to any classes, including ORM models:

require 'r18n-core/translated'

class Product
  include DataMapper::Resource
  property :title_ru, String
  property :title_en, String

  include R18n::Translated
  translations :title
end

# For example, user know only Russian

# Set value to English (default) title
product.title_en = "Anthrax"
product.title #=> "Anthrax"

# Set value to title on user locale (Russian)
product.title = "Сибирская язва"
product.title #=> "Сибирская язва"

product.title_en #=> "Anthrax"
product.title_ru #=> "Сибирская язва"

See R18n::Translated for documentation.

Locale

All supported locales are storage in R18n gem at locales dir. If you want to add your locale, please write me to [email protected].

To get information about locale create R18n::Locale instance:

locale = R18n::Locale.load('en')

You can get from locale:

  • Locale title and RFC 3066 code:

    locale.title #=> "English"
    locale.code  #=> "en"
    
  • Language direction (left to right, or right to left for Arabic and Hebrew):

    locale.ltr? #=> true
    
  • Week start day (“sunday” or “monday”):

    locale['week']['start'] #=> "sunday"
    

Add locale

If R18n hasn’t locale file for your language, please add it. It’s very simple:

  • Create in locales/ file code.yml for your language and describe locale. Just copy from another locale and change different values.

    • If your language is dialect or base on another (as American English (en-US) base on English (en)) write include: base_locale and similar values can be deleted.

    • If in your country people mostly know another language (like in exUSSR countries people know Russian), write sublocales: [another_locale, en]. Else write only: sublocales: [en]. For dialect put base locale to sublocales too.

  • Create in base/ file code.yml for your language and translate base messages. Just copy file from language, which you know, and rewrite values.

  • If you language need some special logic (for example, different pluralization or time formatters) you can change Locale class. Create in locales/ file code.rb and write R18n::Locales::Code class, which must extend R18n::Locale.

  • Push files by GitHub (github.com/ai/r18n) or just write e-mail with this files to me ([email protected]).

Code is RFC 3066 code for your language (for example, “en” for English and “fr_CA” for Canadian French). You can send to my e-mail any questions (on sitnik.ru you find another contact addresses).

License

R18n is licensed under the GNU Lesser General Public License version 3. You can read it in LICENSE file or in www.gnu.org/licenses/lgpl.html.

Author

Andrey “A.I.” Sitnik <[email protected]>