Software engineering notes

Rails I18n

Introduction

當網站會需要多國語言顯示的話, 就會用到 i18n

使用 UI 介面方便翻譯人員協助翻譯

原生基本用法

config/locales/en.yml :

en:
  posts: 'Posts'

config/locales/zh-TW.yml :

'zh-TW':
  posts: '文章'

controllers/welcome_controller.rb :

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
  @current_lang = session[:locale].nil? ? 'zh-TW' : session[:locale]
end

view :

<%= link_to "繁體中文", locale: "zh-TW" %>
<%= link_to "English", locale: "en" %>
<p><%= t('posts') %></p>

對應 DB 欄位

activerecord:
  attributes:
    user:
      real_name: '真實姓名'
      nickname: '暱稱'

當 validate 失敗後的 errors.full_messages 就會把它的 i18n 帶上了

Lazy Lookup

app/views/books/index.html.erb

<%= t '.title' %>

config/locales/en.yml

es:
  books:
    index:
      title: "Título"

支援子目錄

假如語系分成子目錄, ex: locales/zh-TW/welcome.yml

config/application.rb

class Application < Rails::Application
    config.i18n.load_path += Dir["#{Rails.root.to_s}/config/locales/**/*.{rb,yml}"]
end

tolk

Install

gem 'will_paginate'
group :development do
    gem 'tolk'
end

1) Init

$ rake tolk:setup

    ?  Do you want to install the optional configuration file (to change mappings, locales dump location etc..) ? Press <enter> for [Y] >
        create  config/initializers/tolk.rb
        create  db/migrate/20150712075442_create_tolk_tables.rb
    ?  Where do you want to mount tolk? Press <enter> for [tolk] >
        gsub  config/routes.rb
        gsub  config/routes.rb
        route  mount Tolk::Engine => '/tolk', :as => 'tolk'
    (自動執行 db:migrate)
    (讀取 zh-TW.yml)

(選) 限制 tolk 只能用在 dev 環境, routes.rb

if Rails.env.development?
    mount Tolk::Engine => '/tolk', :as => 'tolk'
end

(選) 將 zh-TW 為主要的語言(取決開發上方便使用的語言)

config/initializers/tolk.rb (貼在 Tolk.config do |config| 外面)

Tolk::Locale.primary_locale_name = 'zh-TW'

2) 重新啟動 Rails, 到 http://127.0.0.1:3000/tolk

看是否可以正常看到 tolk 頁面

更新翻譯

它會將主要語言的 yml 檔為主做更新(例如我設 zh-TW 我主要), 如果 key 不存在了, tolk 的資料庫也會清除

rake tolk:sync

再到 /tolk 頁面, 如果沒有看到顯示未翻譯的數量 (蠻常發生這個狀況), 就重新啟動 Rails

翻譯完成後按 save change, 最後把 yml 檔匯出

rake tolk:dump_all

它會產生所有非 tolk 預設語言的 yml 檔, 匯出在 config/locales

後記

如果 zh-TW 是子目錄裡面檔案依 controller name 分 i18n, 在 dump 後的 en 會是將所有 key 合在 en.yml 的

建議

因為 tolk dump 出來的東西會包含其他 gem 的 i18n, 並且以英文字母作為排序,

假如我是以 zh-TW 做主要開發的語言, 那麼就不要 dump zh-TW,

以免這份檔被加入其他 gem 的 i18n 給搞髒了

(其他, 不常用) dump 指定語言的 yaml

rake tolk:dump_yaml["zh-TW"]

(其他, 不常用) 重新 import

rake tolk:import

lit

介紹

當翻譯需要別人參與且需要讓他可以使用 Web UI 協助翻譯, 可以使用這個套件

Get started

1) Gemfile :

gem 'lit'

Init :

rails g lit:install
What's the authentication function, ie. :authenticate_user! : :authenticate_user!           # 使用 devise 做驗證
What's the key value engine? ([hash] OR redis): hash

for production/staging environment redis is suggested as key value engine. hash will not work in multi process environment

2) 接著它會自動做以下這些事

3) 讓 lit 知道哪些語言需要翻譯

config/application.rb 加上 :

config.i18n.available_locales = [:"zh-TW", :en]

之後如果要增/減支援的語言也是改這個地方, 如果減一個語言, 頁面上沒有更新, 就把整個 db 環境重 build 再重新 rails

3) 重啟 Rails, 再回到首頁

在 Rails startup 時會預先載入 config/locale/*.yml 裡的 Keys

接著點擊到的頁面上如果有使用到 I18n.t() 的地方 (例如 devise 的 users/sign_in), 也會建立 key / value 到 lit 的資料庫裡

4) 到 http://127.0.0.1:3000/lit/, 看是否頁面正常顯示

因為先前使用 :authenticate_user! 驗證是否登入, 沒登入會被導到 users/sign_in

登入後裡面只會看到 enzh-TW, 兩種語言

5) 測試

  1. 新增 comments i18n key

  2. 到 view 顯示, 它會自動進到 lit db

  3. 在 lit 後台就會看到了, 翻譯完後, 雖然頁面正常顯示, 但 zh-TW.yml 還是一樣沒變

因為 lit 只負責幫你把翻譯的字串寫到它的資料表中

  1. 匯出在 lit 後台翻譯好的結果:LOCALES=en,zh-TW rake lit:export

    $ LOCALES=en,zh-TW rake lit:export

    I, [2015-07-12T14:19:13.790566 #14791] INFO – : initializing Lit Successfully exported config/locales/lit.yml.