JT's Blog

Do the right things and do the things right.

Rails I18n 多語系

| Comments

國際化的設計,根據不同使用者採用不同的語言、數字格式、日期格式,簡稱i18n

i18n 多語系

Rails 預設是使用英文(en),如要使用i18n 多語系,則需安裝 rails-i18n gem

1
gem 'rails-i18n'

設定載入路徑、預設語系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#config/application.rb

# 設定載入路徑
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
# or
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '*.{rb,yml}').to_s]

# 設定預設語系 zh or en
config.i18n.default_locale = :"zh-TW"
# or
config.i18n.default_locale = :en

# use default locale when translation missing
config.i18n.fallbacks = true
# or
config.i18n.fallbacks = :"zh-TW"

public i18n api

translate:Lookup text translations

1
2
3
I18.t('store.title')
# or
t('store.title')

localize:Localize Date and Time objects to local formats

1
2
3
I18.l(Time.now)
#or
l(Time.now)

自訂語彙

  • 詞彙檔放在 config/locales
  • 使用 YAML 格式
  • 命名方式:***.語系.yml。例如:zh-TW.yml、devise.zh-TW.yml
1
2
3
4
5
6
# config/locales/zh-TW.yml
zh-TW:
    hello: "親愛的%{name}你好!"
    admin:
        user: 使用者管理
        event: 活動管理

注意 YAML 格式的縮排必須使用兩個空格,Tab是不允許的。直接複製貼上可能會有問題,請小心檢查縮排

YAML 格式

  • 第一層:語系
  • 第二層:自訂名稱、或是 rails 保留字,如:controller、activerecord…

I18n.t

使用 I18n.t 根據設定的語系,替換對應的詞彙

在 View 可使用 t 這 Helper 方法,第二參數傳入 Scope

1
2
t("admin.event")
t(:event, scope: :admin)

如果不在View中,則需要加上 I18n 類別

1
I18n.t("admin.event")

template 傳入參數,第二參數傳入變數

1
t(:hello, name: current_user.name) # 親愛的James你好!

使用 YAML 特性加入陣列

1
2
3
4
5
6
7
8
9
10
11
# config/locales/zh-TW.yml
zh-TW:
  date:
    day_names:
    - 星期日
    - 星期一
    - 星期二
    - 星期三
    - 星期四
    - 星期五
    - 星期六

透過 i18n 取得陣列資料

1
I18n.t('date.day_names', locale: 'zh-TW')

變化:使用 i18n.t 設定網頁條款

1
2
3
4
5
6
7
8
zh-TW:
  example:
    policy_html:
      <h1>使用條款</h1>
      # ...
    privacy_html:
      <h1>隱私條款</h1>
      # ...

在 view 呼叫 i18n.t

1
2
<%= t('example.policy_html') %>
<%= t('example.privacy_html') %>

Lazy Lookup (Convension)

設定語彙檔

1
2
3
4
5
# config/locales/zh-TW.yml
zh-TW:
  books:
    index:
      title: 標題

如果在 app/views/books/index.html.erb 使用 I18n book.index.title 可以縮寫如下:

1
<%= t '.title' %>

搭配 Model 使用

根據 model name 建立對應的語彙檔

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
zh-TW:
  activerecord:
    models:
      brand: 品牌
      category: &category 分類
    attributes:
      brand:
        created_at: *created_at
        name: 名稱
    errors:
      messages:
        record_invalid: "校驗失敗: %{errors}"
        restrict_dependent_destroy:
          has_one: 由於 %{record} 需要此記錄,所以無法移除記錄
          has_many: 由於 %{record} 需要此記錄,所以無法移除記錄

第二層為 activerecord

第三層 models 設定 model 語彙名稱

1
Brand.model_name.human # zh-TW => 品牌

設定 attributes

1
Brand.human_attribute_name("name") # zh-TW => 名稱

設定 errors

1
activerecord.errors.messages.record_invalid(errors: '尚未輸入資料')

如何讓使用者切換語系

1
2
3
4
5
6
7
8
9
10
11
# controllers/application_controller.rb
before_action :set_locale

def set_locale
  # 可以將 ["en", "zh-TW"] 設定為 VALID_LANG 放到 config/environment.rb 中
  if params[:locale] && I18n.available_locales.include?( params[:locale].to_sym )
    session[:locale] = params[:locale]
  end

  I18n.locale = session[:locale] || I18n.default_locale
end
1
2
3
4
5
# views/..
<%= link_to "中文版", :controller => controller_name,
:action => action_name, :locale => "zh-TW" %>
<%= link_to "English", :controller => controller_name,
:action => action_name, :locale => "en" %>

Reference

Comments