1. Mở đề

Khi start một dự án rails, mình thường lấy các yêu cầu từ phía khách hàng. Và một trong những cái mình quan tâm đầu tiên là có cần đối ứng multi language hay không?
Và chúng ta hay biết trong từ chuyên ngành là i18n. Nếu xác định từ đầu là có chức năng này, thì khi code chung ta sẽ tốn chút time cho việc tạo ra các file language YML.
Nhưng khi chuyển sang 1 ngôn ngữ nào khác bạn chỉ cần mang các file này đi dịch sang thứ ngôn ngữ mà bạn muốn hiện thị thêm trên website của bạn làm.
Từ đâu mà có từ i18n này?
"Quốc Tế Hoá" - Internationalization, thì giữa chữ i và chữ n có 18 chữ, nên viết tắt lại là i18n.
Ngoài ra có 1 sự thật tình cờ mình phát hiện ra là nếu bạn đếm từ chữ i tới chữ n trên bàn phím từ trái qua phải thì sẽ có 18 ký tự từ i tới n 😲

2. i18n cơ bản

  1. Cấu hình:
    Thường 1 project trong file application.rb mình sẽ thêm các thông tin như sau:
1. class Application < Rails::Application
      ...
2.    config.time_zone = "Asia/Tokyo"
3.    config.i18n.default_locale = :ja
4.    I18n.available_locales = [:ja, :tw]
5.    config.i18n.load_path += Dir["#{Rails.root.to_s}/config/locales/**/*.yml"]
      ...
6. end

Khi mà bạn không định nghĩa config.i18n.load_path thì chỉ load mỗi file default (nếu default_locale là :ja thì là file ja.yml ở trong folder locales)

  1. Cách dùng.
    Các bạn có thể dùng i18n ở trong các file controler (class) hoặc view file .erb
    Nếu mình có 1 file có các cấp như sau:
ja:
  shop:
    orders:
      update:
        update_fail: エラーが発生しました

Để get nội dung i18n ra mình có các cách như sau:

Cách 1: Dùng full key path tới message cần dùng

I18n.t 'shop.orders.update.update_fail'

Cách 2: Nếu mình dùng key update_fail, ở trong controller orders và action update, mình dùng như sau, rails sẽ tìm theo controller và action cho mình (Hay còn gọi là "Lazy" Lookup)
Nhưng nếu bạn dùng ngoài action update của orders controler thì phải dùng full key path nhé.

I18n.t '.update_fail'

_

  1. Cách set thêm default valule nếu value của key bị miss (không get được)
I18n.t :update_fail, default: 'Please try again'
# => 'Please try again'

Nhưng nếu dùng như trên sẽ mất tính i18n của source nên thay vì thế định nghĩa message default ở trong file i18n luôn và mình sẽ có như sau:

I18n.t :update_fail, default: :try_again
# => 'Please try again'

Mình sẽ kiểm tra, và bổ sung thêm các set default message mà không dùng Symbol xem có được không? 👬

  1. Cách truyền tham số vào cho mesage
    Khi dùng tham số thì mình thêm các param dạng %{tên_param} vào message như sau:
  shop:
    orders:
        message: "明日は%{name}さんが来ます。%{date}"

Khi mình gọi thì sẽ như sau:

I18n.t "shop.orders.message", name: user.name, date: I18n.l(scheduled_date, format: :long)

3. i18n và Tiếng Nhật

Trong tiếng Nhật thì mình hay dùng nhất là các message, câu văn dài hoặc phải xuống hàng.

  1. Đối với 1 câu văn dài:

Các bạn có thể thêm ký tự > sau dấu : của key như sau

order:
   text_message: >
     明日はきっといい日になる
     いい日になる
     いい日になるでしょう

Kết quả bạn sẽ có 1 hàng dài và mỗi enter xuống hàng của bạn sẽ được thay bằng 1 khoảng trắng

I18n.t "order.text_message"
=> "明日はきっといい日になる いい日になる いい日になるでしょう"
  1. Đối với 1 đoạn văn có nhiều dòng

Các bạn có thể thêm ký tự | sau dấu : của key như sau

order:
   text_message: |
     明日はきっといい日になる
     いい日になる
     いい日になるでしょう

Và đây là kết quả

I18n.t "order.text_message"
=> "明日はきっといい日になる\n" + "いい日になる\n" + "いい日になるでしょう"

4. Kết

Với một số chia sẽ như trên giúp các bạn mới làm quen với i18n một cách dễ dàng.
Ngoài ra để hiểu rõ hơn các bạn tham khảo 1 số link sau đây.

  1. Rails Internationalization (I18n) API
  2. In YAML, how do I break a string over multiple lines?

5. Will be updated soon

Mình sẽ update 1 sô cách dùng I18n hưu ích trong HTML và cách định nghĩa scope trong i18n sớm vào bài viết này.