Mezinárodní marketing

Internacionalizace v Rails: od URL adres po JavaScript

Internacionalizace v Rails: od URL adres po JavaScript
Aktualizováno dne
18. května 2026

Rails obsahuje integrovaný framework pro internacionalizaci. K tomu, abyste mohli začít, toho moc víc nepotřebujete – rozhraní I18n API je součástí balíku a základní funkce zvládá dobře: překlad statických řetězců, formátování dat a čísel a správu množného čísla v různých jazykových mutacích.

„Integrované“ však neznamená „kompletní“. Jakmile se vaše požadavky rozšíří na lokalizované URL adresy, překlady v JavaScriptu nebo vícejazyčné SEO, dostanete se mimo rámec toho, co Rails standardně nabízí. Tyto mezery vyžadují promyšlená architektonická rozhodnutí.

Projdeme si obě vrstvy: co zajišťuje API Rails I18n a kde budete muset něco naprogramovat – nebo tuto úlohu přenechat jinému.

Co pokrývá lokalizace v Rails I18n a kde končí

Rozhraní API I18n nabízí dvě základní metody: I18n.t pro překlad řetězců a I18n.l pro lokalizaci dat a čísel. Obě čtou ze souborů YAML nebo Ruby v adresáři config/locales/ a Rails je při spuštění načte automaticky.

Ve výchozím nastavení to zahrnuje statické řetězce uživatelského rozhraní, formátování datumu a čísel a validační hlášení ActiveRecord. Pro většinu projektů, kde se překládá z jednoho jazyka do druhého, to k vydání stačí.

Jakmile se dostanete dál, mezery se rychle projeví.

Rails I18n se nijak nevyjadřuje ke struktuře URL: neposkytuje lokalizované trasy, detekci subdomén ani předpony cest. Neobsahuje žádný mechanismus pro překlad obsahu uloženého v databázi, jako jsou názvy produktů nebo příspěvky na blogu. Soubory JavaScriptu se nacházejí zcela mimo tento proces. A vícejazyčné SEO, tedy například tagy hreflang, přeložené slugy a jazykově specifické soubory sitemap, vyžaduje samostatnou práci, do které se framework nezapojuje.

Než začnete stavět, musíte vědnit, kde vede hranice.

Vytvoření základů pro mezinárodní lokalizaci

Začít můžete s gemem rails-i18n.

Rails dodává pouze data pro anglické národní prostředí, takže bez nich selže volání I18n.l(Date.today) v jiných národních prostředích než anglickém a řetězce na úrovni frameworku, jako jsou například validační zprávy Active Record, zůstanou v angličtině bez ohledu na aktuální národní prostředí.

# Gemfile

gem "rails-i18n"

Poté nastavte výchozí hodnoty aplikace:

# config/application.rb

config.i18n.default_locale = :en

config.i18n.available_locales = [:en, :fr]

config.i18n.enforce_available_locales = true

Nastavení `enforce_available_locales = true` vyvolá chybu, pokud se aplikace pokusí nastavit národní prostředí mimo tento seznam. Bez tohoto nastavení může překlep nebo nesprávně zadaný parametr URL v produkčním prostředí tiše nastavit nepodporované národní prostředí.

Ačkoli moderní Rails prohledává pouze jednu úroveň, často mu uniknou hluboce vnořené složky (například config/locales/views/products/). Přidáním tohoto řádku zajistíte, že se při rozšiřování vaší aplikace zahrnou všechny podadresáře:

config.i18n.load_path += Dir[Rails.root.join("config", "locales", "**", „*.{rb,yml}“)]

Díky tomu můžete překladové soubory rozdělit podle domén:

config/locales/  
	en/    
		models.yml    
		views.yml    
		mailers.yml  
	fr/    
		modely.yml    
		views.yml    
		mailers.yml

⚠️ YAML interpretuje hodnoty jako true a false jako logické hodnoty. Pokud je potřebujete jako doslovný text, uveďte je výslovně v uvozovkách. Moderní verze Ruby/YAML nyní zacházejí s výrazem yes a no jako s řetězci, ale jejich uvozování zůstává bezpečným zvykem z důvodu kompatibility:

cs:  
	odpovědi:    
		ano: „ano“    
		záporné: „ne“

Tím se odhalí určitý druh chyby, která se projeví pouze v případě, že překlad vrátí hodnotu „true“ namísto „yes“ a váš zobrazení nevykreslí nic, nebo v horším případě řetězec „true“.

Pomocné funkce pro překlad a odložené vyhledávání v Views

Ve viewech jsou t a l dva pomocné prvky, které budete používat neustále.

Funkce `l` lokalizuje data, časy a čísla podle aktuálního národního prostředí. Je-li nainstalován modul `rails-i18n`, jsou součástí balíčku definice formátů pro více než 100 národních prostředí. Bez něj však volání `l(Date.today)` v jiném než anglickém národním prostředí obvykle vrátí řetězec „translation missing“ nebo neformátované datum, protože Rails postrádá potřebné lokalizované formátovací šablony.

<%= l(Date.today) %>

<%= l(Date.today, format: :long) %>

t překládá řetězce podle klíče. Plný zápis je t("products.index.title"), ale ve výpisech můžete použít zkrácený zápis s odloženým vyhledáváním:

<%= t(".title") %>

Úvodní tečka sděluje Railsům, aby klíč vyhodnotily relativně k aktuální cestě k zobrazení. V souboru app/views/products/index.html.erb se výraz t(".title") automaticky rozbalí na t("products.index.title"). Díky tomu zůstávají klíče krátké a bez dalšího úsilí se dodržuje jednotná konvence pojmenování.

For interpolation, use %{variable} in your YAML and pass the value as a keyword argument:

en:  
	welcome: "Hello, %{name}"
<%= t(".welcome", name: current_user.name) %>

Pokud překlad obsahuje HTML kód, kterému důvěřujete, připojte k názvu klíče příponu _html. Rails jej automaticky označí jako bezpečný, aniž by bylo nutné volat metodu html_safe.

en:  
	notice_html: "Please <strong>confirm</strong> your email."

Odložené vyhledávání funguje pouze v případech, kdy si Rails dokáže odvodit cestu k zobrazení, což znamená, že nefunguje v úlohách na pozadí ani v API řadičích. V těchto případech vždy použijte úplný klíč.

Výběr strategie pro detekci národní lokalizace

Než začnete psát kód pro detekci jazykového prostředí, zvolte si strategii. Existuje pět hlavních přístupů a ten správný závisí na struktuře vaší aplikace a požadavcích na SEO.

Strategie Příklad Nejlepší pro
Parametr URL /products?locale=fr Interní nástroje, rychlé prototypování
Předpona cesty /fr/produkty Veřejné weby vyžadující vícejazyčné SEO
Subdoména fr.example.com Charakteristické regionální značky
TLD příklad.fr Domény s národními koncovkami, které již vlastníte
Nastavení databáze Uloženo v záznamu uživatele Ověřené aplikace s uživatelskými nastaveními

Předpona adresy, například /fr/products, je nejčastější volbou pro veřejně přístupné aplikace v Rails. Díky ní je v každé URL explicitně uvedeno jazykové nastavení, což vyhledávačům umožňuje indexovat stránky samostatně pro každý jazyk.

Strategie využívající subdomény a domény nejvyšší úrovně (TLD) se osvědčují, pokud chcete posílit regionální identitu, ale s sebou přinášejí další práci s konfigurací DNS a správou SSL certifikátů.

Parametry URL, jako například /products?locale=fr, jsou vhodné pro interní nástroje, u nichž na SEO nezáleží.

Předvolby uložené v databázi fungují u ověřených aplikací, kde se národní prostředí řídí podle uživatele, nikoli podle adresy URL.

Ať už se rozhodnete pro jakoukoli strategii, existuje jedna chyba při implementaci, která způsobuje nenápadné chyby v produkčním prostředí: přímé použití I18n.locale =.

# Don't do this

before_action { I18n.locale = params[:locale] }

I18n.locale = zapisuje do proměnné Thread.current.

Pokud používáte webový server Puma, ten využívá vlákna napříč jednotlivými požadavky. Pokud požadavek výslovně nenastaví národní prostředí, převezme nastavení z předchozího požadavku.

Při lokálním vývoji v jednovláknovém prostředí se tento problém nikdy neprojeví. V produkčním prostředí však způsobuje občasné odpovědi v nesprávném jazyce, které je obtížné reprodukovat a ještě obtížnější vysledovat.

Místo toho použijte metodu I18n.with_locale uvnitř akce around_action:

around_action :switch_locale‍d


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

Funkce `with_locale` obnoví původní národní prostředí po ukončení bloku, bez ohledu na to, jak žádost skončí.

Implementace lokalizovaných tras a detekce subdomén

Definujte své trasy v adresáři /:locale a předefinujte nastavení `default_url_options`, aby Rails automaticky předřazoval aktuální národní prostředí ke každé URL-pomocné funkci:

# config/routes.rb
scope "/:locale" do
  resources :products
  root "home#index"
end

# app/controllers/application_controller.rb
around_action :switch_locale

def switch_locale(&action)
  locale = params[:locale]
  # Fallback to default if the param is missing or unsupported
  valid_locale = I18n.available_locales.map(&:to_s).include?(locale) ? locale : I18n.default_locale
  I18n.with_locale(valid_locale, &action)
end

def default_url_options
  { locale: I18n.locale }
end

Je-li nastavena proměnná `default_url_options`, adresa `products_path` se automaticky zobrazí jako `/fr/products`, pokud je aktuální národní nastavení `:fr`.

Pokud chcete, aby výchozí lokalizace předponu vynechala, nastavte segment jako volitelný s rozsahem „(:locale)“. Tím se pro angličtinu zobrazí /products a pro francouzštinu /fr/products, ale vznikne tím nejednoznačnost. Cesta typu /about by se mohla vztahovat buď na chybějící lokalizaci, nebo na řadič s názvem about, v závislosti na pořadí tras.

Při detekci subdomén nejprve načtěte hodnotu z `request.subdomains.first` a porovnejte ji s `available_locales`, než provedete jakékoli nastavení:

def extrahovat_jazyk_z_subdomény
  subdomain = request.subdomains.first
  vrátit nil if subdomain.blank? || subdomain == "www"
  subdomain if I18n.available_locales.map(&:to_s).include?(subdomain)
end

Kontrola www zabraňuje tomu, aby byl považován za národní prostředí. Na localhostu vrací request.subdomains prázdné pole, takže detekce subdomén ve vývojovém prostředí selže, pokud nepoužíváte server Pow nebo nepřidáte záznamy do souboru /etc/hosts.

Jednu věc je třeba nastavit zvlášť: proměnná `default_url_options` definovaná v `ApplicationController` se nepřenáší do modulů pro odesílání e-mailů ani do úloh na pozadí. V těchto kontextech ji nastavte výslovně:

Rails.application.routes.default_url_options = { host: "example.com", locale: :en }

Lokalizované trasy vám poskytnou strukturu URL, avšak tagy hreflang, přeložené slugy a vícejazyčné soubory Sitemap je i po tomto nastavení třeba zadávat zcela ručně.

Integrace reverzního proxy Weglot tuto úroveň zpracovává automaticky a generuje tagy hreflang a jazykově specifické URL adresy bez nutnosti další konfigurace.

Pluralizace, náhradní řešení a gem rails-i18n

Tvorba množného čísla v angličtině je jednoduchá. Jedna forma pro jednotné číslo, jedna pro všechny ostatní případy.

en:
  messages:
    one: "%{count} message"
    other: "%{count} messages"

Většina jazyků není tak jednoduchá.

Například bulharština má u některých slov v mužském rodě pravidelný plurál a speciální „počítací plurál“. Slovo ден (den) se tedy běžně mění na дни (mnoho dní), ale při počítání se používá dva дена (dva dny).

bg:
  cities:
    one: "%{count} ден"
    few: "%{count} дена"
    many: "%{count} дни"

Bez modulu rails-i18n nemá Rails o těchto pravidlech žádné informace. Vaše bulharské překlady by se při každém počítání buď zobrazovaly s chybou, nebo by se přepnuly na druhou formu.

Gem obsahuje logiku pro tvorbu množného čísla pro více než 100 jazykových verzí, takže se vše správně zobrazí v bulharštině, ruštině, arabštině, polštině a v jakémkoli jiném jazyce s odlišnými pravidly pro tvorbu množného čísla než v angličtině.

Náhradní řešení představují samostatný problém a ve výchozím nastavení jsou vypnutá. Bez nich se při chybějícím překladovém klíči v produkčním prostředí zobrazí hlášení o chybějícím překladu. Právě takové chyby se dostávají do finální verze a objevují se na snímcích obrazovky.

Zapněte záložní řešení a definujte výchozí cíl v souboru config/application.rb:

config.i18n.fallbacks = [I18n.default_locale]

Je-li nastaveno `fallbacks = true`, chybějící klíč v aktuálním národním prostředí se nahradí hodnotou z `default_locale`. Pro regionální varianty můžete definovat explicitní řetězce:

config.i18n.fallbacks = { "fr-CA": :fr, "en-GB": :en }

Nastavte to včas. Dodatečné zavedení záložního chování do aplikace, která již má v produkčním prostředí částečné překlady, je složitější než jeho nastavení hned na začátku.

Předávání překladů do ovladačů Stimulus a do JavaScriptu

JavaScript nemá přístup k procesu lokalizace v Rails.

K dispozici není žádný pomocný modul t, načítací program YAML ani vestavěný most mezi překladovými soubory a řadiči Stimulus. Překlady je nutné předávat explicitně ze strany serveru.

Nejjednodušším způsobem v rámci Stimulus je použití API hodnot. Překlad definujte jako hodnotu v řadiči, nastavte jej v HTML a načtěte jej v JavaScriptu:

# app/views/products/index.html.erb
<div data-controller="notification"
     data-notification-message-value="<%= t('.success_message') %>">

Hodnota se vykresluje na straně serveru pomocí standardního pomocného modulu `t`, takže automaticky zohledňuje aktuální národní prostředí. Na straně JavaScriptu ji deklarujte jako statickou hodnotu a načtěte ji pomocí rozhraní API `values`:

// app/javascript/controllers/notification_controller.js
export default class extends Controller {
  static values = { message: String }

  show() {
    alert(this.messageValue)
  }
}

Každý překlad je explicitní a ohraničený na konkrétní řadič, který jej potřebuje. Do globálního rozsahu se nic neprojeví.

Pokud správce potřebuje více překladů najednou, je přehlednější seskupit je do jednoho atributu datového formátu JSON, než přidávat jednotlivé definice hodnot pro každý řetězec:

<div data-controller="cart"
     data-cart-i18n-value="<%= { add: t('.add'), remove: t('.remove') }.to_json %>">

V JavaScriptu deklarujte i18n jako hodnotu typu Object a přistupujte přímo k jednotlivým klíčům:

static values = { i18n: Object }

add() {
  console.log(this.i18nValue.add)
}

V případě aplikací, kde JavaScript potřebuje široký přístup k překladům napříč mnoha řadiči, gem i18n-js exportuje vaše soubory YAML do objektu JavaScriptu, který můžete dotazovat pomocí I18n.t("key").

Funguje to, ale přidává to další krok při sestavování a klientovi se tak odešle kompletní sada překladů. Používejte to v případě, že se první dva postupy začnou opakovat, nikoli jako výchozí nastavení.

Při používání Turbo Frames platí, že pokud URL zdroje Turbo Frames neobsahuje předponu locale, dojde obvykle k selhání požadavku s chybou směrování (404), protože nebude odpovídat vzoru rozsahu „/:locale“. Pro zdroje rámců vždy používejte pomocné funkce pro cesty zohledňující locale.

Nejde o chybu systému Turbo. Jedná se spíše o opomenutí při směrování, kterému zabraňuje akce `around_action` z části pro detekci locale, a to za předpokladu, že každá URL v rámci používá pomocný prvek pro cesty s podporou locale.

Reverzní proxy Weglot využívá zcela odlišný přístup. Překládá vykreslený DOM až po načtení stránky, takže obsah vykreslený pomocí Stimulus a dynamicky vkládané řetězce jsou pokryty bez jakéhokoli tohoto propojování.

Co v systému Rails I18n chybí

Existují tři kategorie, které zcela nespadají do působnosti funkce Rails I18n:

  • V rámci vícejazyčného SEO v Rails i18n sice překládá řetězce, ale nevytváří tagy hreflang, jazykově specifické soubory sitemap ani přeložená metadata. Tyto úkoly vyžadují ruční práci nad rámec nastavení i18n.
  • Obsah uložený v databázi, jako jsou názvy produktů a příspěvky na blogu, nelze ukládat do souborů YAML. K tomuto účelu se doporučuje gem Mobility, který podporuje více úložných backendů. Traco je odlehčenější alternativou pro menší modely s překlady na úrovni jednotlivých sloupců.
  • Pracovní postup překladu v Rails se opírá o soubory YAML. Řízení překladatelského procesu, revizní cykly, aktualizace a synchronizace překladů s aplikací je nutné řešit mimo rámec tohoto frameworku.

Weglot řeší všechny tyto problémy na úrovni výstupu, nikoli na úrovni kódu:

  • Namísto integrace do překladového procesu Rails I18n překládá tento nástroj již vygenerovaný HTML kód, který vaše aplikace vytváří. To znamená, že obsah databáze, řetězce vykreslené pomocí JavaScriptu i statické překlady jsou zpracovávány stejným způsobem.
  • Součástí je vícejazyčné SEO/GEO: tagy hreflang, přeložené URL adresy a soubory Sitemap se generují automaticky.
  • Pracovní postup překladatele probíhá prostřednictvím ovládacího panelu Weglot, nikoli prostřednictvím exportu do formátu YAML.

Je však třeba si uvědomit několik omezení, o kterých byste měli vědět, než se k tomuto řešení vyjádříte:

  • Tento snippet v JavaScriptu není indexován pro účely SEO; aby se přeložené stránky zobrazovaly ve výsledcích vyhledávání, je nutné nastavit reverzní proxy.
  • Funkce vlastního směrování do podadresářů, která se hodí v případě, že již máte nastavenou konfiguraci CDN nebo Nginx, je k dispozici pouze v rámci verze Enterprise.
  • Na rozdíl od překladů zabudovaných přímo do vašeho kódu Weglot aktivní předplatné, aby byl přeložený obsah nadále viditelný.

Výběr architektury pro internacionalizaci v Rails

Každá implementace i18n v Railsu spočívá ve stejných rozhodnutích, která se provádějí zhruba ve stejném pořadí.

Nejprve si zvolte strategii pro URL, než začnete psát kód pro detekci národního prostředí. U většiny aplikací určených pro veřejnost stačí segmenty adresy. Subdomény mají smysl tam, kde záleží na regionální identitě. Předvolby uložené v databázi se hodí pro aplikace vyžadující přihlášení, kde se národní prostředí přizpůsobuje uživateli, nikoli URL.

Za druhé, rozhodněte se, jakým způsobem bude JavaScript získávat překlady. API Stimulus values pokrývá většinu případů. Atributy JSON se hodí v situacích, kdy řadič potřebuje více řetězců najednou.

Za třetí, rozhodněte se, co budete vytvářet ručně. Rails si se statickými řetězci poradí dobře. SEO vrstva, pracovní postup překladatelů i obsah databáze vyžadují samostatná rozhodnutí. Můžete si vše vytvořit sami, nebo výstupní vrstvu svěřit nástroji, jako je Weglot čas vývojářů soustředit na samotnou aplikaci.

Vynechejte výstupní vrstvu úplně. Vyzkoušejte Weglot na 14 dní Weglot a získejte vícejazyčné SEO/GEO, přeložené URL adresy a automatickou detekci obsahu, aniž byste museli zasahovat do svého kódu pro internacionalizaci.

ikona směru
Objevte Weglot

Přidejte se k více než 110 000 značkám, které už překládají své weby s Weglotem

Přeložte svůj web okamžitě s pomocí AI, doladíte ho lidskými úpravami a spustíte ho během několika minut.

V tomto článku se podíváme na:
Ikona rakety

Jste připraveni začít?

Nejlepší způsob, jak pochopit sílu Weglot vyzkoušet si ho na vlastní kůži. Vyzkoušejte ho zdarma a bez jakýchkoli závazků.

Pokud ještě nejste připraveni propojit svůj web, je k dispozici demo webová stránka ve vašem ovládacím panelu.

Přečtěte si články, které by se vám mohly líbit

Ikona FAQ

Časté dotazy

Nic nebylo nalezeno.

Modrá šipka

Modrá šipka

Modrá šipka