R18n for Rails
R18n-rails is a gem to add out-of-box R18n support to Rails I18n.
It is a wrapper for R18n Rails API and R18n core libraries. See R18n core documentation for more information.
Features
R18n for Rails is fully compatibile with Rails I18n, and add extra features:
R18n Syntax
You can use more compact, explicit and ruby-style syntax.
Translations in R18n format will be loaded from app/i18n/locale.yml
:
user:
name: User name is %1
count: !!pl
0: No users
1: 1 user
n: %1 users
R18n extends t
helper to add optional R18n syntax:
t.user.name('John') #=> "User name is John"
t.user.count(5) #=> "5 users"
t.not.exists | 'default' #=> "default"
Filters
R18n has flexible architecture based on filters. Variables, pluralization, untranslated are common filters, and you can change them all. For example, write untranslated keys to file:
R18n::Filters.add(::R18n::Untranslated, :write_untranslated) do
|v, c, translated, untranslated, path|
File.open('untranslated.list', 'w') do |io|
io.puts(path)
end
end
R18n already has filters for HTML escaping, lambdas, Textile and Markdown:
hi: !!markdown
**Hi**, people!
greater: !!escape
1 < 2 is true
i18n.hi #=> "<p><strong>Hi</strong>, people!</p>"
i18n.greater #=> "1 < 2 is true"
Model Translation
R18n can add i18n support for your ActiveRecord model and any other class (include DataMapper, MongoMapper, Mongoid):
-
Add separate columns for all supported translations:
def self.up create_table :posts do |t| t.string :title_en t.string :title_ru end end
-
Add virtual method
title
, which will usetitle_locale
methods to find actual translation:class Post < ActiveRecord::Base include R18n::Translated translations :title end # For Russian user post = Post.new post.title_en = 'Post' post.title_ru = 'Запись' post.title = 'Запись' post.title = 'Другая' # will use title_ru, by first user's locale
Time Fomatters
R18n add full
time formatter based on locale info:
# English
l Time.now, :full #=> "1st of December, 2009 12:00"
# French
l Time.now, :full #=> "1er décembre 2009 12:00"
Locales
R18n contains locales info, so it supports locale pluralization and fallback rules for non-English locales out-of-box:
# Russian have different plural rules:
user:
count: !!pl
0: Нет пользователей
1: %1 пользователь
2: %1 пользователя
n: %1 пользователей
t.user.count(2) #=> "2 пользователя"
t.user.count(21) #=> "21 пользователь"
Autodetect User Locales
R18n automatically generate fallbacks for current user, based on user locales list from HTTP_ACCEPT_LANGUAGE, locale info (in some countries people know several languages), and default locale.
For example, if user know Kazakh and German, R18n will try find translations in: Kazakh → German → Russian (second language in Kazakhstan) → English (default locale).
Separated I18n
You can create another R18n I18n instance with another languages. For example, to send e-mail for English admin on error with French user:
puts I18n.t :error # Show error in French
admin_i18n = R18n::I18n.new(@admin_locales, Rails.root + 'app/i18n')
send_email(admin_i18n.)
How To
-
Add
r18n-rails
gem to yourconfig/environment.rb
:config.gem 'r18n-rails'
Now R18n will autodetect user locales.
-
Define your way to set locale manually. R18n will find it in
params[:locale]
orsession[:locale]
. Best way is a put optional locale prefix to URLs:map.connect ':controller/:action' map.connect ':locale/:controller/:action'
-
Print available translations, to choose from them manually (and to helpsearch engines):
<ul> <% r18n.available_locales.each do |locale| %> <li> <a href="/<%= locale.code %>/"><%= locale.title %></a> </li> <% end %> </ul>
-
Translations in I18n format are stored in
config/locales/locale.yml
:en: user: name: "User name is %{name}" count: zero: "No users" one: "One user" many: "%{count} users"
Translations in R18n format go to
app/i18n/locale.yml
:user: name: User name is %1 count: !!pl 0: No users 1: 1 user n: %1 users
-
Use translated messages in views. You can use Rails I18n syntax:
t 'user.name', :name => 'John' t 'user.count', :count => 5
or R18n syntax:
t.user.name(:name => 'John') # for Rails I18n named variables t.user.name('John') # for R18n variables t.user.count(5)
-
Print dates and numbers in user’s tradition:
l Date.today, :standard #=> "20/12/2009" l Time.now, :full #=> "20th of December, 2009 12:00" l 1234.5 #=> "1,234.5"
-
Translate models:
-
Add to migration columns for each of the supported locales, named as
name_locale
:t.string :title_en t.string :title_ru t.string :text_en t.string :text_ru
-
Add
R18n::Translated
mixin to model:class Post < ActiveRecord::Base include R18n::Translated
-
Call
translations
method in model with all columns to be translated:translations :title, :text
Now model will have virtual methods
title
,text
,title=
andtext=
, which will calltitle_ru
ortitle_en
and etc based on current user locales.
You can use
R18n::Translated
mixin for any Ruby class, not only for ActiveRecord models. -
-
Download translations for Rails system messages (validation, etc) from github.com/svenfuchs/rails-i18n/tree/master/rails/locale and put them to
config/locales/
(because them use Rails I18n format).
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]>