מדריך מלא לבינאום (i18n) ב-Rails
הגדירו I18n ב-Rails, ארגנו את config/locales/*.yml, בצעו אוטומציה לתרגומי YAML באמצעות בינה מלאכותית, ואפשרו ל-PTC (Private Translation Cloud) לסקור את אפליקציית ה-Rails הפעילה שלכם בכל גרסה. בסוף המדריך תהיה לכם אפליקציית Rails שמגיבה לכתובות /es/..., מגישה תצוגות (views) מתורגמות ליותר מ-40 שפות, ומאומתת באמצעות סקירה חזותית.
מדריך זה מניח שיש לכם אפליקציית Rails 7+ קיימת. המושגים תקפים גם לגרסאות Rails ישנות יותר עם הבדלי API מינוריים. ה-gem של I18n עצמו יציב כבר שנים. לסיפור המלא של לוקליזציה בצינורות CI/CD על פני סטאקים שונים, ראו לוקליזציה של תוכנה מבוססת בינה מלאכותית שנבנתה עבור צינורות CI/CD.
הגדרת Rails לטעינת לוקאלים, זיהוי כתובות URL והחלפת שפה לפי בקשה
בינאום ב-Rails דורש שלושה שלבי הגדרה: הגדרת הלוקאלים הזמינים, הוספת הלוקאל לכתובות ה-URL שלכם, והגדרת Rails כך שתטען את הלוקאל הנכון בכל בקשה. בנוסף, יש להתקין את ה-gem rails-i18n עבור נתוני הלוקאל.
הצהרה על לוקאלים זמינים ב-config/application.rb
בתוך config/application.rb, הגדירו באילו שפות האפליקציה תומכת וקבעו ברירת מחדל:
module MyApp
class Application < Rails::Application
config.i18n.available_locales = [:en, :es, :fr, :de, :ja]
config.i18n.default_locale = :en
config.i18n.fallbacks = true
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
end
end
השורה load_path += Dir[...] היא שורת המפתח. כברירת מחדל, Rails טוענת רק את config/locales/*.yml (ברמה אחת בלבד). הוספת ה-glob הרקורסיבי מאפשרת לכם לארגן תרגומים לפי namespace, מודל או פיצ'ר בתוך תיקיות משנה.
הוספת :locale לטווח (scope) של כתובות ה-URL
הוסיפו scope של :locale כדי שלכל שפה יהיה נתיב משלה, כמו /en/time או /es/time:
# config/routes.rb
scope "/:locale" do
get '/time', to: 'home#index', as: :time_display
end
החלפת לוקאל לכל בקשה באמצעות I18n.with_locale
ב-ApplicationController, טענו את הלוקאל הנכון מה-URL וכללו אותו בכל הקישורים הנוצרים:
class ApplicationController < ActionController::Base
around_action :switch_locale
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
השימוש ב-I18n.with_locale הוא הדרך האידיומטית להגביל לוקאל לבקשה מסוימת. הוא מגדיר את הלוקאל, מריץ את הבלוק, משחזר את הלוקאל הקודם, והוא בטוח לשימוש בסביבת ריבוי נימים (thread-safe). הפונקציה default_url_options מבטיחה שכל URL ש-Rails מייצרת יישא את הלוקאל הנוכחי, כך שהמשתמשים יישארו בשפה שבחרו בזמן הניווט.
התקנת rails-i18n עבור שמות חודשים מתורגמים וכללי ריבוי
ה-gem rails-i18n מספק נתוני לוקאל לעשרות שפות: שמות חודשים מתורגמים, כללי ריבוי והודעות שגיאה המוגדרות כברירת מחדל ב-Rails. כך לא תצטרכו לתרגם את התשתית הזו בעצמכם.
# Gemfile
gem 'rails-i18n'
bundle install
אפליקציית ה-Rails שלכם מוגדרת כעת באופן מלא לבינאום.
הוספת בורר שפות עם url_for(locale: :code)
מכיוון ש-default_url_options כולל אוטומטית את הלוקאל בכל URL שנוצר, בורר השפות שלכם צריך רק לעדכן את הפרמטר :locale תוך השארת המשתמש באותו דף.
<%# app/views/layouts/application.html.erb %>
<nav class="language-switcher">
<%= link_to "English", url_for(locale: :en) %> |
<%= link_to "Espanol", url_for(locale: :es) %> |
<%= link_to "Deutsch", url_for(locale: :de) %>
</nav>
כל קישור משתמש ב-url_for(locale: :code) כדי ליצור URL עם הלוקאל המצוין. כאשר משתמשים לוחצים עליו, switch_locale ב-ApplicationController מזהה את השינוי ו-Rails מרנדרת את הדף בשפה החדשה.
החלפת טקסט קשיח (hardcoded) בתצוגות באמצעות t(:key)
טקסט קשיח לא יופיע בקובצי ה-YAML שלכם, מה שאומר שלא ניתן יהיה לתרגם אותו. השתמשו תמיד במפתחות תרגום לכל טקסט הפונה למשתמש.
<%# Correct - uses translation keys %>
<h1><%= t(:hello) %></h1>
<p><%= t(:current_time, time: @time) %></p>
<button id="click-me"><%= t(:refresh) %></button>
<%# Incorrect - hardcoded text %>
<h1>Hello</h1>
<p>Current time: <%= @time %></p>
<button>Refresh</button>
בבקרים (עבור הודעות flash):
def create
if @post.save
redirect_to @post, notice: t('flash.post.created')
else
flash.now[:alert] = t('flash.post.error')
render :new, status: :unprocessable_entity
end
end
במודלים (עבור הודעות אימות, השתמשו במוסכמות של Active Model):
# config/locales/en.yml
en:
activerecord:
attributes:
post:
title: "Title"
errors:
models:
post:
attributes:
title:
blank: "is required"
שיבוץ משתנים (interpolation) באמצעות %{name}
הביטוי %{name} ב-YAML מוחלף בערך שאתם מעבירים ל-t():
current_time: "Current time: %{time}"
<%= t(:current_time, time: @time) %>
שימוש בחיפוש עצל (lazy lookup) עבור תרגומים מוגבלי תצוגה
כאשר מפתחות התרגום שלכם מאורגנים כך שיתאימו למבנה תיקיות התצוגה, השתמשו בנקודה בתחילת המפתח. Rails תשלים את הקידומת מהתצוגה הנוכחית:
<%# Instead of this: %>
<%= t('home.index.hello') %>
<%# Use this: %>
<%= t('.hello') %>
Rails מזהה שאתם נמצאים ב-home/index.html.erb ומוסיפה את הקידומת home.index.. אם תשנו שם או מיקום של תצוגה, נתיבי החיפוש העצל יתעדכנו אוטומטית.
ארגון config/locales/ לפי פיצ'רים במקום קובץ en.yml ענק אחד
באפליקציה אמיתית, קובץ en.yml ענק אחד הופך לבלתי ניתן לתחזוקה. ארגנו לפי פיצ'ר:
config/locales/
en.yml # global / shared keys
models/
post.en.yml
views/
posts.en.yml
home.en.yml
flash.en.yml
דוגמה לקובץ config/locales/views/posts.en.yml:
en:
posts:
index:
title: "All Posts"
empty: "No posts yet"
new:
title: "Create a New Post"
show:
published_at: "Published %{date}"
comments_count:
zero: "No comments yet"
one: "1 comment"
other: "%{count} comments"
מוסכמות:
- מפתחות מקוננים מקבצים מחרוזות קשורות ומאפשרים חיפוש עצל.
- שיבוץ
%{name}עבור משתנים בתוך השורה. - מפתחות ריבוי
zero/one/otherעבור שמות עצם ספירות. Rails מנתבת למפתח הנכון על סמךcount::t('posts.show.comments_count', count: 5).
הוספת מחרוזות JavaScript ל-YAML גם כן
Rails אינה מחלצת אוטומטית טקסט מקובצי JavaScript. כל טקסט בצד הלקוח (התראות, חלוניות עזרה, הודעות אישור) צריך להימצא ב-YAML שלכם כדי שיחול עליו תרגום לצד כל השאר:
en:
confirm: "Are you sure?"
כאשר תתרגמו באמצעות PTC בסעיף הבא, המחרוזות הללו יעברו יחד עם השאר.
תרגום config/locales/*.en.yml באמצעות PTC ב-4 שלבים
ברגע שקובצי התרגום שלכם מוכנים, אתם זקוקים לגרסאות עבור כל שפת יעד. PTC מטפל בכך:
- התחילו פרויקט PTC ובחרו באנגלית כשפת המקור. תקופת הניסיון בחינם מכסה 20,000 מילים ל-2 שפות, ללא כרטיס אשראי.
- העלו את קובצי ה-
config/locales/*.en.ymlשלכם. PTC מנתח את ה-YAML, מזהה מפתחות ריבוי של Rails (zero, one, other, few, many), ומשמר את שיבוצי ה-%{name}. - הוסיפו תיאור קצר של אפליקציית ה-Rails שלכם וקהל היעד. PTC משתמש בהקשר זה כדי לתרגם בטון ובטרמינולוגיה הנכונים.
- בחרו שפות יעד ואשרו. PTC מייצר את
posts.es.yml, posts.fr.yml, posts.de.yml, הזהים מבנית למקור עם ערכים מתורגמים. צורות ריבוי נוצרות לפי שפה. פולנית מקבלתone/few/many/other. יפנית מקבלת רקother.
החזירו את הקבצים ל-config/locales/views/, הפעילו מחדש את שרת ה-Rails שלכם, והאפליקציה תגיש את השפות החדשות.
עבור פרויקטים מבוססי Git, חברו את PTC למאגר שלכם. מחרוזות חדשות בכל *.en.yml יפעילו תרגום אוטומטי. PTC יפתח pull request עם קובצי שפות היעד המעודכנים. ראו את API reference של PTC עבור תהליך הסנכרון.
שימוש ב-I18n.with_locale בתהליכי רקע, מיילרים ומשימות cron
התבנית I18n.with_locale(locale, &block) קריטית לכל קוד שרץ מחוץ לבקשה רגילה: תהליכי רקע, משימות cron ומיילרים.
# Background job: send an email in the user's preferred locale
class WelcomeEmailJob < ApplicationJob
def perform(user_id)
user = User.find(user_id)
I18n.with_locale(user.preferred_locale) do
UserMailer.welcome(user).deliver_now
end
end
end
ללא with_locale, התהליך ירוץ בלוקאל שהיה פעיל כשה-worker התחיל, בדרך כלל :en, ללא קשר להעדפת המשתמש. בעזרתו, המייל ירונדר בשפת המשתמש והלוקאל יאופס בסיום הבלוק.
ייצוא תרגומי Rails ל-JSON באמצעות i18n-js לשימוש בצד הלקוח
דפים המרונדרים ב-Rails מקבלים תרגומים דרך t() ב-ERB. קוד JavaScript שרץ בדפדפן לא רואה את ה-I18n של Rails ישירות. התבנית הנקייה ביותר משתמשת ב-gem i18n-js כדי לייצא תרגומים כ-JSON ולטעון אותם בצד הלקוח.
# Gemfile
gem 'i18n-js'
bundle install
i18n init
עדכנו את ההגדרה שנוצרה כדי לייצא תרגומים ל-public/locales.json:
# config/i18n.rb
require "i18n-js"
I18n::JS.config do |config|
config.export_i18n_js = false
config.translations_path = "public/locales.json"
end
צרו את קובץ ה-JSON:
i18n export
פעולה זו קוראת את כל קובצי ה-YAML שלכם (en.yml, es.yml, de.yml) וכותבת את public/locales.json עם כל תרגום בפורמט קריא ל-JS.
בצעו pin ל-i18n-js עם Importmap ב-Rails 7+:
# config/importmap.rb
pin "i18n-js", to: "https://esm.sh/i18n-js@latest/dist/import/index.js"
pin "load_locale", to: "load_locale.js"
צרו טוען (loader):
// app/javascript/load_locale.js
export async function loadLocale() {
const response = await fetch('/locales.json');
return await response.json();
}
העבירו את הלוקאל הנוכחי ל-JavaScript דרך תגית ה-<body>:
<%# app/views/layouts/application.html.erb %>
<body data-locale="<%= I18n.locale %>">
לאחר מכן השתמשו בתרגומים בתוך ה-JavaScript שלכם:
// app/javascript/application.js
import { I18n } from "i18n-js";
import { loadLocale } from "./load_locale";
document.addEventListener('turbo:load', async () => {
const translations = await loadLocale();
const i18n = new I18n(translations);
i18n.locale = document.body.dataset['locale'];
if (confirm(i18n.t('confirm'))) {
// User clicked OK
}
});
הפונקציה i18n.t() עובדת כמו ה-helper t של Rails. כשמשתמשים מחליפים שפות, ה-JavaScript משתמש בתרגומים הנכונים מתוך המאפיין data-locale.
תרגום תוכן ActiveRecord באמצעות ה-API של PTC
התבנית שלעיל מתרגמת מחרוזות סטטיות בקובצי ה-YAML שלכם. תוכן ActiveRecord (פוסטים של משתמשים, תגובות, תיאורי מוצרים המאוחסנים כקלט משתמש) אינו מופיע ב-YAML ודורש גישה שונה. ה- REST API של PTC מתרגם תוכן זה לפי דרישה עם אימות Bearer-token, תוך שימוש באותו מילון מונחים וטון מותג כמו קובצי ה-config/locales/*.yml שלכם. שלחו את התוכן שלכם ב-POST ל-PTC, ולאחר מכן קבלו callback כשהתרגומים מוכנים או בדקו סטטוס (polling) מתוך תהליך רקע.
לוקליזציה של תאריכים, מספרים ומטבעות באמצעות ה-helpers של Rails
תאריכים ושעות. השתמשו ב-helper l (קיצור של localize):
<%= l Time.now, format: :long %>
ה-gem rails-i18n מספק פורמטים של תאריך/שעה כברירת מחדל לשפות רבות, כולל שמות חודשים מתורגמים ועיצוב ספציפי ללוקאל. ניתן להגדיר פורמטים מותאמים אישית בקובצי ה-YAML שלכם.
מספרים ומטבעות. Rails כוללת helpers המודעים ללוקאל:
<%= number_to_currency(100, locale: :es) %> <!-- 100,00 EUR -->
<%= number_with_delimiter(1000000) %> <!-- 1,000,000 -->
אלו מכבדים את מוסכמות הלוקאל עבור מפרידים עשרוניים, מפרידי אלפים וסימני מטבע.
תצוגות מותאמות ללוקאל לכל שפה. עבור דפים עם תוכן שונה משמעותית בכל לוקאל, צרו קובצי תצוגה נפרדים. Rails מרנדרת את התצוגה המתאימה על סמך הלוקאל הנוכחי:
app/views/pages/
about.html.erb <!-- Default -->
about.es.html.erb <!-- Spanish version -->
about.de.html.erb <!-- German version -->
סקירת תרגום חזותית של אפליקציית ה-Rails הפעילה שלכם – הפצה ללא QA ידני בכל גרסה
לאחר ש-PTC מתרגם את ה-config/locales/*.yml שלכם, אפליקציית ה-Rails המרונדרת עדיין זקוקה לאימות. טקסט מתורגם עלול לחרוג מגבולות הכפתור בגרמנית. הודעת אימות בצרפתית עלולה להשתמש בצורה דקדוקית שגויה. מחרוזת אנגלית קשיחה בתבנית ERB (ללא קריאה ל-t()) תרונדר ללא תרגום ללא קשר למספר השפות שאתם מפיצים.
ה-AI Visual QA של PTC מחליף את שלב ה-QA הידני. עבור אפליקציות Rails (מבוססות דפדפן), התקינו את ה-תוסף לדפדפן של PTC והקליטו walkthrough של המסכים הקריטיים באפליקציה (כניסה, תהליכים מרכזיים, דפי ניהול). מאותו רגע, PTC מריץ מחדש את ההקלטה בכל שפת יעד לאחר כל עדכון תרגום, לוכד כל מסך ומדווח:
- תיקונים בקובצי ה-YAML כאשר PTC שולט בהם. PTC מתרגם מחדש משמעות שגויה, בוחר מילה נרדפת קצרה יותר או מייצר מחדש צורת ריבוי.
- הנחיות (prompts) ל-Cursor / Claude Code כאשר הבעיה נמצאת בקוד ה-Ruby או ה-ERB שלכם. מחרוזת אנגלית קשיחה מחוץ ל-
t(), הודעת flash שנבנתה באמצעות שרשור במקום שיבוץ, או helper שצריך להשתמש ב-I18n.lעבור עיצוב תאריך.
התוצאה: אפליקציית Rails רב-לשונית מאומתת בכל גרסה. לא רק קובצי YAML מתורגמים.
תרגום הערות גרסה, מיילרים של Devise ודפי שיווק
הערות הגרסה שלכם, מיילים הפונים ללקוחות שנשלחים דרך Devise או Action Mailer ודפי שיווק נמצאים מחוץ ל-config/locales. הכלי Paste to Translate של PTC מטפל בטקסטים אלו באותו פרויקט. הדביקו את טקסט המקור בלוח הבקרה של PTC, בחרו שפות יעד, וקבלו תרגומים המשתמשים באותו מילון מונחים וטון מותג כמו תרגומי ה-YAML שלכם.
תרגמו את קובצי ה-config/locales/*.yml שלכם באמצעות PTC
התחילו תקופת ניסיון של 30 יום בחינם – 20,000 מילים ל-2 שפות, ללא כרטיס אשראי. העלו את קובצי ה-YAML שלכם, קבלו גרסאות מתורגמות תוך דקות, ולאחר מכן התקינו את תוסף הדפדפן כדי לאמת את אפליקציית ה-Rails הפעילה שלכם.
נושאים קשורים:
- API reference של PTC – נקודות קצה REST לאינטגרציית CI.
- לוקליזציה של תוכנה מבוססת בינה מלאכותית שנבנתה עבור צינורות CI/CD – סקירת שירות עבור צוותי הנדסה.
- מדריך ה-i18n הרשמי של Rails – המקור המוסמך.