Skip to main content Link Search Menu Expand Document (external link)

Internationalization

This article will teach you how to translate your Rails application into different languages, how to work with translations, and how to switch locales.

Table of Contents

  1. What is Internationalization?
  2. Ruby I18n (Internationalization)
  3. Create translation
  4. Translate with parameter
  5. Model Translation
  6. Language Switcher

What is Internationalization?

Internationalization is a development approach that makes it easier to adapt a project to the language and cultural differences of a location other than the one where it was created.

Ruby I18n (Internationalization)

Rails applications has a built-in I18n gem, which is a comprehensive internationalization tool. I18n is a simple and extensible framework for translating the application to a single custom language other than English or for implementing multi-language support in applications. By default, the language of I18n is English.

Create translation

To do our multilingual feature, we need to create the translation vocabulary file (YAML) with its name based on the language locale code, then afterward, call the I18n function to replace the hard-coded content in the template.

Let’s make our posts page an example. Go to config/locales and open en.yml file. The en.yml file contains your vocabulary for english. Add another translation for post list.

# config/locales/en.yml

en:
  hello: "Hello world"
+ post_list: Post List

Two spaces must be used for indentation in YAML format. Always check the indention of your yaml file carefully.

Change the posts page header, call the translation method.

<!-- app/views/posts/index.html.erb -->

- <h1>Post List</h1>
+ <h1><%= t('post_list') %></h1>
  <!-- ... -->

Read Carefully:

The method t is short for I18n.t, it is a Helper method that will replace strings according to the language it belongs.

Now, let’s try making a translation for Chinese. The I18n locale code for simplified chinese is zh-CN.

# config/locales/zh-CN.yml

zh-CN:
  post_list: 活動清單

To change language, just set I18n.locale with the language locale code. To make an example, let’s change language temporarily.

# app/controllers/posts_controller.rb

class PostsController < ApplicationController
  #...
  def index
+   I18n.locale = 'zh-CN'
    #...
end

Translate with parameter

In some instances, a sentence may require a variable, for cases like this, we can use %{variable_name} syntax in our translation. Let’s try making a translation with parameter.

# config/locales/en.yml

# ...
en:
- hello: "Hello world"
+ hello: "Hello, %{name}"
  post_list: Post List
# config/locales/zh-CN.yml

zh-CN:
+ hello: "您好, %{name}"
  post_list: 活動清單

Display it in our application layout.

<!-- app/views/layouts/application.html.erb -->

<!DOCTYPE html>
  <!-- ... -->
    <%= t( 'hello', name: current_user.email) if current_user %>
    <%= yield %>
  </body>
</html>

Model Translation

Model name and its attributes can also have a translation.

# config/locales/model.en.yml

en:
  activerecord:
    models:
      post:
        one: Post
        other: Posts
    attributes:
      post:
        title: Title
        content: Content
# config/locales/model.zh-CN.yml

zh-CN:
  activerecord:
    models:
      post:
        one: 文章
        other: 多篇文章
    attributes:
      post:
        title: 標題
        content: 內容

Separating your translations to make your code organized and clean is a good practice.

Read Carefully:

The translations file name makes no difference, the important thing is that the first layer in the YAML structure corresponds to the name of the locale. Rails will load all the YAML vocabulary file from config/locales.

Call Model.human_attribute_name(:name) to use the translation. Change the table header in posts page.

<!-- app/views/posts/index.html.erb -->

<table>
  <thead>
- <td>title</td>
- <td>content</td>
+ <td><%= Post.human_attribute_name(:title) %></td>
+ <td><%= Post.human_attribute_name(:content) %></td>

Language Switcher

Now that we’ve finished the translations, let’s get started on the switch language feature.

Remove the hardcoded setup of locale language on posts controller index.

# app/controllers/posts_controller.rb

class PostsController < ApplicationController
  #...
  def index
-   I18n.locale = 'zh-CN'
    #...
end

Setup the config for default locale, and available locales.

# config/application.rb

# ...
module App
  class Application < Rails::Application
    # ...
+   config.i18n.default_locale = :en
+   config.i18n.available_locales = [:en, 'zh-CN']
    # Don't generate system test files.
    config.generators.system_tests = nil
  end
end

Then start making the locale setter on our application controller.

# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
+ before_action :set_locale
+
+ def set_locale
+   if params[:locale] && I18n.available_locales.include?( params[:locale].to_sym )
+     session[:locale] = params[:locale]
+   end
+
+   I18n.locale = session[:locale] || I18n.default_locale
+ end
  # ...
end 

Finally, add a link for switching language on our application layout.

<!-- app/views/layouts/application.html.erb -->

<!-- ... -->
+   <%= link_to 'EN', params.permit!.merge(locale: 'en') %>
+   <%= link_to 'zh-CN', params.permit!.merge(locale: 'zh-CN') %>
    <%= yield %>
  </body>
</html>

That is all for internationalization.


Back to top

Copyright © 2020-2022 Secure Smarter Service, Inc. This site is powered by KodaCamp.