Home / Blog / Internationalization for Ruby with the r18n gem

Internationalization for Ruby with the r18n gem

Developer resources
Helmut Juskewycz
CEO & Founder of LingoHub

Last updated

8/22/2013

Read time

8 min

Best for

Developers

You create - Lingohub localizes

The previous two articles on internationalization for Ruby have covered the usage of the i18n gem in detail. This article will introduce an alternative: R18n including usage of the r18n gem.

ruby1

R18n is an internationalization tool used for building multilingual Ruby applications. It contains a core gem and out-of-the-box wrapper plugins for frameworks or environments (Rails, Sinatra, desktop).

Some of its features include Ruby-style syntax, filters, model (or Ruby object) translation, auto-detection of user locales, flexible locales, and general extensibility.

Just like the i18n gem (Internationalization for Ruby) described previously, the default resource file format for R18n is YAML. File names should correspond to the locale used.

Here is a sample en.yml file used in the examples:

Example YAML gist


Installation and setup of the r18n gem

Install the gem:

gem install r18n-core

After installing, start the console in the directory where the YAML file is located, require the library, and configure it:

require 'r18n-core'

R18n.default_places = './'
R18n.set('en')

Translation lookup with r18n

To access translations, use R18n.t or t when including R18n::Helpers.

R18n.t.greetings.hello.world
# => "Hello World!"

With helpers:

include R18n::Helpers

t.greetings.hello.world
# => "Hello World!"

Translation object behavior

t.class
# => R18n::Translation

t.greetings.class
# => R18n::Translation

t.greetings.hello.world.class
# => R18n::TranslatedString

Missing translations and fallbacks

If a translation is missing, an Untranslated object is returned.

t.greetings.hello.everybody
# => R18n::Untranslated

Check existence:

t.greetings.hello.everybody.translated?
# => false

Fallback value:

t.greetings.hello.everybody | 'default'
# => "default"

Interpolation

Pass variables as arguments:

t.greetings.hello.user 'stranger', 'our site'
# => "Hello stranger, welcome to our site"

Missing arguments simply leave placeholders blank:

t.greetings.hello.user
# => "Hello , welcome to "

Filters for translation processing

Filters allow processing translations (HTML escaping, Markdown, Textile, lambdas, etc.).

Example YAML:

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

greater: !!escape
  1 < 2 is true

greater_no_filter:
  1 < 2 is true

alarm: !!textile
  It will delete *all* users!

Example usage:

t.greater
# => "1 < 2 is true"

t.hi
# => "<p>Hi, <strong>people</strong>!</p>\n"

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

Lambdas

sum: !!proc |x, y| x + y
t.sum
# => 3

Disable filters:

R18n::Filters.off(:procedure)

Pluralization

Mark pluralized keys with !!pl:

inbox:
  messages: !!pl
    0: Your inbox is empty.
    1: You have one message in your inbox.
    n: You have %1 messages in your inbox.

Usage:

t.inbox.messages 0
# => "Your inbox is empty."

t.inbox.messages 1
# => "You have one message in your inbox."

t.inbox.messages 39
# => "You have 39 messages in your inbox."

Localization

Use R18n::l or l helper.

Numbers

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

Time and date formatting

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

Built-in formats:

l Time.now, :human
# => "now"

l Time.now, :full
# => "August 9th, 2009 21:47"

l Time.now
# => "08/09/2009 21:41"

l Time.now.to_date
# => "08/09/2009"

Translating models and Ruby objects

Add localized fields in migrations:

t.string :title_en
t.string :title_ru

t.string :text_en
t.string :text_ru

Include translation module:

class Post < ActiveRecord::Base
  include R18n::Translated

  translations :title, :text
end

Usage:

post = Post.first

R18n.set('en')
post.title
# => "English title"

R18n.set('ru')
post.title
# => "Russian title"

Locale settings

Locales are stored in the gem’s locales directory:

R18n locales directory

Inspect locale info:

locale = R18n.locale('en')

locale.title
# => "English"

locale.code
# => "en"

locale.ltr?
# => true

locale.week_start
# => :sunday

Rails and Sinatra wrappers

Rails integration

r18n-rails
r18n-rails-api

Install:

gem 'r18n-rails'

Usage examples:

t 'user.name',  name: 'John'
t 'user.count', count: 5

t.user.name(name: 'John')
t.user.name('John')

t.user.count(5)

Sinatra integration

r18n-sinatra

Setup:

require 'sinatra/r18n'

Optional config:

# R18n::I18n.default = 'ru'
# R18n.default_places { './translations' }

For modular apps:

class YourApp < Sinatra::Base
  register Sinatra::R18n
  set :root, File.dirname(__FILE__)
end

Locale routing:

get '/:locale/posts/:id' do
  @post = Post.find(params[:id])
  haml :post
end

Session-based locale:

before do
  session[:locale] = params[:locale] if params[:locale]
end

Helper usage:

t.hello('Ela')
# => "Hello Ela"

R18n vs i18n

Feature

i18n

r18n

Translation

t :hello, username: 'Ela'

t.hello('Ela')

YAML format

Hello, %{username}

Hello, %1

Pluralization

multiple keys (one/few/many)

!!pl with numeric keys

Example:

t('robots', count: 1)
# => "1 robot"

vs

t.robots(1)
# => "1 robot"

Further reading

Related articles