Table of content
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.

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:
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:
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
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
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 |
|
|
YAML format |
|
|
Pluralization | multiple keys (one/few/many) |
|
Example:
t('robots', count: 1)
# => "1 robot"
vs
t.robots(1)
# => "1 robot"
Further reading
Related articles

i18n gem advanced features - Ruby on Rails internationalization
Find inside this article the highlighting of some i18n gem advanced features in Ruby on Rails internationalization.
Internationalization (I18n) API in Ruby on Rails 3 (Part I)
Learn about the Internationalization (I18n) API in Rails 3, including its definition, mechanism, setup, configuration, and usage with interpolation and pluralization.
Internationalization (I18n) API in Ruby on Rails 3 (Part II)
Learn about the Internationalization (I18n) API in Rails 3, including its definition, mechanism, setup, configuration, and usage with interpolation and pluralization.
Internationalization (I18n) API in Ruby on Rails 3 (Part III)
This article is the third part of the Ruby series, where we will delve into some of the more advanced features of I18n. Read it and the previous two parts in our blog