Skip to main content

Rails i18n : คู่มือการทำให้ Ruby on Rails รองรับหลายภาษาอย่างครบถ้วน

ตั้งแต่ไฟล์ภาษาแรกจนถึงระบบจริง กำหนด Rails I18n ใช้ตัวช่วย t() จัดการพหูพจน์ CLDR แก้ปัญหาพบบ่อย และเพิ่มลำดับภาษาสำรองอัจฉริยะ

1

ทำความเข้าใจสถาปัตยกรรม Rails I18n

Rails มี gem I18n ในตัว ไฟล์แปลอยู่ใน config/locales/ เป็น YAML (ค่าเริ่มต้น) หรือ Ruby เฟรมเวิร์กมีตัวช่วย t() ซึ่งเป็นชื่อย่อ I18n.translate ในมุมมอง คอนโทรลเลอร์ โมเดล และ mailer Rails I18n ออกแบบให้เรียบง่ายและจัดการการแปล การแทรกค่า และพหูพจน์พื้นฐานให้ทันที

config/application.rb
# Rails includes i18n out of the box via the i18n gem
# config/application.rb
module MyApp
  class Application < Rails::Application
    # Default locale
    config.i18n.default_locale = :en

    # Available locales
    config.i18n.available_locales = [:en, :de, :ja, :es, :fr, :'pt-BR']

    # Fallback to default locale when translation is missing
    config.i18n.fallbacks = true

    # Load translations from nested directories
    config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
  end
end
config/routes.rb
# config/routes.rb
Rails.application.routes.draw do
  scope "/:locale", locale: /en|de|ja|es|fr|pt-BR/ do
    root "home#index"
    resources :products
  end

  root "home#index"
end

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  around_action :switch_locale

  private

  def switch_locale(&action)
    locale = params[:locale] || I18n.default_locale
    I18n.with_locale(locale, &action)
  end

  def default_url_options
    { locale: I18n.locale }
  end
end
Rails โหลดไฟล์ .yml และ .rb ทั้งหมดจาก config/locales/ อัตโนมัติ จัดตามภาษา (en.yml, de.yml) ตามฟีเจอร์ (en/users.yml, en/orders.yml) หรือทั้งสองก็ได้ Rails จะผสานทุกไฟล์ตอนเริ่มต้น
2

กำหนดค่าภาษา

ตั้ง default_locale, available_locales และพฤติกรรมค่าสำรองใน config/application.rb หรือ initializer กำหนดการตรวจภาษาใน ApplicationController ด้วย before_action ซึ่งตั้งจาก URL เซสชัน คุกกี้ หรือส่วนหัว Accept-Language

config/locales/en.yml
# config/locales/en.yml
en:
  nav:
    home: "Home"
    about: "About"
    settings: "Settings"
  greeting: "Hello, %{name}!"
  cart:
    item_count:
      one: "%{count} item"
      other: "%{count} items"

# config/locales/de.yml
de:
  nav:
    home: "Startseite"
    about: "Über uns"
    settings: "Einstellungen"
  greeting: "Hallo, %{name}!"
  cart:
    item_count:
      one: "%{count} Artikel"
      other: "%{count} Artikel"
การตั้ง I18n.locale ใน before_action ปลอดภัยรายคำขอ แต่ I18n.default_locale ขณะรันเป็นส่วนกลางและกระทบทุกเธรด ใช้ I18n.locale ซึ่งเป็น thread-local สำหรับการเปลี่ยนภาษารายคำขอเสมอ ไม่ใช้ I18n.default_locale
3

ใช้ตัวช่วย t()

ตัวช่วย t() ใช้ได้ทั่ว Rails ทั้งมุมมอง คอนโทรลเลอร์ โมเดล mailer และงาน รับคีย์ ตัวแปรแทรกเสริม และตัวเลือกอย่างค่าเริ่มต้นกับขอบเขต ในมุมมอง Rails รองรับการค้นหาแบบ lazy ที่กำหนดขอบเขตตามคอนโทรลเลอร์และการทำงานปัจจุบัน

app/views/example.html.erb
# In views (ERB)
<h1><%= t('nav.home') %></h1>
<p><%= t('greeting', name: @user.name) %></p>

# In controllers
flash[:notice] = t('flash.product_created')

# In models
validates :name, presence: { message: I18n.t('errors.blank') }

# With HTML (safe)
<%= t('terms_html', link: link_to(t('terms_link'), '/terms')) %>
4

จัดการพหูพจน์

Rails I18n ใช้หมวดหมู่พหูพจน์ CLDR ได้แก่ zero, one, two, few, many, other อังกฤษใช้เพียง one กับ other แต่ภาษาอื่นต้องใช้มากกว่า กำหนดคำแปลพหูพจน์เป็นคีย์ YAML ซ้อนใต้หมวดหมู่ที่ภาษาเป้าหมายต้องใช้

Plural forms
# In YAML:
en:
  cart:
    item_count:
      zero: "No items"
      one: "%{count} item"
      other: "%{count} items"

# Arabic (6 forms):
ar:
  cart:
    item_count:
      zero: "لا عناصر"
      one: "عنصر واحد"
      two: "عنصران"
      few: "%{count} عناصر"
      many: "%{count} عنصرًا"
      other: "%{count} عنصر"

# Usage in views:
<%= t('cart.item_count', count: @cart.items.size) %>
Rails จะโยน I18n::InvalidPluralizationData หากไม่มีหมวดหมู่ที่ภาษาปัจจุบันต้องใช้ หากรัสเซียกำหนดเพียง one กับ other ซึ่งคัดลอกจากอังกฤษ จำนวน 2, 3, 4 จะทำให้แอปหยุดเพราะต้องมี few ให้กำหนดทุกหมวดหมู่ CLDR ของแต่ละภาษา
5

เพิ่มลำดับการใช้ภาษาสำรอง

I18n.fallbacks ในตัวของ Rails มีค่าสำรองพื้นฐานจากภูมิภาคไปยังภาษาเริ่มต้น ผู้ใช้ pt-BR ที่ไม่มีคีย์จึงเห็นอังกฤษแทน pt-PT rails-locale-chain เพิ่มลำดับแบบผสานเชิงลึกที่กำหนดค่าได้ เพื่อให้เห็นคำแปลใกล้เคียงที่สุด

Lazy lookups
# Lazy lookups use the controller/action as scope
# app/views/products/index.html.erb
# Instead of t('products.index.title'), just use:
<h1><%= t('.title') %></h1>
<p><%= t('.description') %></p>

# Rails looks up: products.index.title and products.index.description

# config/locales/en.yml
en:
  products:
    index:
      title: "All Products"
      description: "Browse our catalog"
rails-locale-chain มีลำดับสำเร็จรูปมากกว่า 75 รายการใน 11 ตระกูลภาษา เพิ่มใน Gemfile กำหนดใน initializer แล้วผู้ใช้ภูมิภาคจะเห็นคำแปลภาษาหลักแทนช่องว่างอังกฤษ
6

ทำให้การแปลเป็นอัตโนมัติ

เมื่อตั้งค่า Rails I18n เสร็จแล้ว ให้แปลไฟล์ YAML ด้วย AI i18n Agent รองรับ YAML โดยตรง ชี้ไปยังไฟล์ต้นฉบับแล้วระบบจะสร้างทุกภาษาเป้าหมาย พร้อมรักษาคีย์ซ้อน ตัวแปรแทรก และรูปพหูพจน์

config/initializers/locale_chain.rb
# Gemfile
gem 'rails-locale-chain'

# config/initializers/locale_chain.rb
Rails.application.config.i18n.fallbacks = {
  'pt-BR': ['pt', 'en'],
  'zh-Hant-TW': ['zh-Hant', 'zh', 'en'],
  'es-419': ['es', 'en'],
}

# The gem deep-merges translations across the chain
# pt-BR -> pt -> en
# Missing keys in pt-BR are filled from pt, then en
แปลแบบเพิ่มทีละส่วน เมื่อเพิ่มคีย์ใหม่ ให้แปลเฉพาะส่วนต่าง วิธีนี้ช่วยรักษาคำแปลเดิมและไม่สร้างข้อความที่ไม่เปลี่ยนใหม่

ข้อผิดพลาดที่พบบ่อย

ข้อผิดพลาด InvalidPluralizationData

Rails หยุดด้วย I18n::InvalidPluralizationData เมื่อไม่มีหมวดหมู่ CLDR ที่ต้องใช้ มักเกิดเมื่อคัดลอก one/other ของอังกฤษไปยังภาษาที่ต้องมากกว่า เช่น รัสเซียต้อง few และอาหรับต้อง zero/two/few/many ติดตั้ง rails-i18n และกำหนดทุกหมวดหมู่

การค้นหาแบบ Lazy นอกมุมมอง

การค้นหา lazy (t('.key')) ใช้ได้เฉพาะมุมมองที่ Rails รู้คอนโทรลเลอร์และการทำงาน การใช้ในโมเดล mailer หรือบริการจะคืนข้อผิดพลาดคำแปลหาย ใช้คีย์เต็มอย่าง t('users.show.key') นอกมุมมอง

ข้อผิดพลาด YAML ทำให้คำแปลทั้งหมดเสียหาย

ข้อผิดพลาด YAML จุดเดียว เช่น เยื้องผิด อักขระพิเศษไม่ครอบ หรือใช้แท็บแทนช่องว่าง ทำให้ทั้งไฟล์โหลดไม่ได้ ทุกคำแปลจะคืนข้อผิดพลาดคีย์หาย ตรวจ YAML ใน CI ด้วยลินเตอร์และครอบข้อความที่มีทวิภาค วงเล็บ หรืออักขระพิเศษนำหน้า

ลองใช้ i18n Agent ตอนนี้

ลากและวางไฟล์แปลของคุณที่นี่

JSON, YAML, PO, XML, CSV, Markdown, Properties

หรือคลิกเพื่อเลือกไฟล์

ภาษาเป้าหมาย

ไม่ต้องลงทะเบียนประเมินราคาได้ทันที

คำถามที่พบบ่อยเกี่ยวกับ Rails i18n