edge
Daugiau informacijos rubyonrails.org: Daugiau apie Ruby on Rails

Rails Internationalizacijos (I18n) API

Ruby I18n (trumpinys iš tarptautinės) gem, kuris yra pristatomas su Ruby on Rails (pradedant nuo Rails 2.2), suteikia lengvai naudojamą ir išplėstinį pagrindą išversti jūsų programą į vieną pasirinktą kalbą kitą nei anglų arba suteikti daugiakalbės palaikymą jūsų programoje.

"Tarptautinimo" procesas paprastai reiškia išskirti visas eilutes ir kitus vietos specifinius elementus (tokius kaip datos ar valiutos formatavimas) iš jūsų programos. "Lokalizavimo" procesas reiškia suteikti vertimus ir lokalizuotus formatavimus šiems elementams.1

Taigi, tarptautinimo proceso metu jūs turite:

Lokalizavimo proceso metu, jūs, tikriausiai, norėsite atlikti šias tris veiksmus:

Šis vadovas palydės jus per I18n API ir turi vadovėlį, kaip tarptautiškai padaryti Rails programą nuo pradžių.

Po šio vadovo perskaitymo, jūs žinosite:

Pastaba: Ruby I18n pagrindas suteikia jums visus būtinus įrankius jūsų Rails programos tarptautinimui / lokalizavimui. Taip pat galite naudoti įvairius prieinamus gemus, kad pridėtumėte papildomos funkcionalumo ar funkcijų. Daugiau informacijos rasite rails-i18n gem.

1 Kaip veikia I18n Ruby on Rails

Tarptautinimas yra sudėtinga problema. Natūralios kalbos skiriasi taip daug būdų (pvz., daugiskaitos taisyklės), kad sunku suteikti įrankius, kurie išspręstų visus problemas vienu metu. Dėl šios priežasties Rails I18n API yra orientuotas į:

  • palaikyti anglų ir panašias kalbas iš karto
  • padaryti lengva pritaikyti ir plėsti viską kitoms kalboms

Kaip dalis šio sprendimo, kiekviena statinė eilutė Rails pagrindiniame karkase - pvz., Active Record validacijos pranešimai, laiko ir datos formatavimai - yra tarptautinė. Rails programos lokalizavimas reiškia apibrėžti išverstas reikšmes šioms eilutėms norimomis kalbomis.

Norint lokalizuoti, saugoti ir atnaujinti turinį jūsų programoje (pvz., išversti tinklaraščio įrašus), žr. Turinio modelio vertimas skyrių.

1.1 Bibliotekos bendras architektūra

Taigi, Ruby I18n gem yra padalintas į dvi dalis:

  • I18n pagrindo viešasis API - Ruby modulis su viešaisiais metodais, kurie apibrėžia, kaip veikia biblioteka
  • Numatytasis pagrindas (kuris sąmoningai vadinamas Paprastu pagrindu), kuris įgyvendina šiuos metodus

Kaip naudotojas, jūs visada turėtumėte naudoti tik viešuosius metodus I18n modulyje, tačiau naudinga žinoti apie pagrindo galimybes.

Pastaba: Galima pakeisti pristatomą Paprastą pagrindą su galingesniu, kuris saugotų vertimo duomenis reliacinėje duomenų bazėje, GetText žodyne ar panašiai. Žr. skyrių Naudoti skirtingus pagrindus žemiau.

1.2 Viešasis I18n API

Svarbiausi I18n API metodai yra:

translate # Ieškoti teksto vertimų
localize  # Lokalizuoti datos ir laiko objektus į vietinius formatavimus

Jie turi pseudonimus #t ir #l, todėl galite juos naudoti taip:

I18n.t 'store.title'
I18n.l Time.now

Taip pat yra atributų skaitytuvas ir rašytojas šiems atributams:

load_path                 # Pranešti apie savo tinkintus vertimo failus
locale                    # Gaukite ir nustatykite dabartinę lokalę
default_locale            # Gaukite ir nustatykite numatytąją lokalę
available_locales         # Leidžiamos lokalės, prieinamos programai
enforce_available_locales # Taikyti lokalės leidimą (taip arba ne)
exception_handler         # Naudoti kitą exception_handler
backend                   # Naudoti kitą pagrindą

Taigi, pradėkime tarptautiškai padaryti paprastą Rails programą kituose skyriuose!

2 Nustatykite Rails programą tarptautinimui

Yra keletas žingsnių, kad galėtumėte pradėti naudoti I18n palaikymą Rails programoje.

2.1 Konfigūruokite I18n modulį

Laikydamasis "konvencijos prieš konfigūraciją" filosofijos, "Rails I18n" teikia pagrįstus numatytuosius vertimo eilučių variantus. Kai reikalingos skirtingos vertimo eilutės, jas galima perrašyti.

"Rails" automatiškai prideda visus .rb ir .yml failus iš config/locales katalogo į vertimų kelių taką.

Numatytasis en.yml lokalės failas šiame kataloge turi pavyzdinę vertimo eilučių porą:

en:
  hello: "Hello world"

Tai reiškia, kad :en lokalėje raktas hello bus susietas su eilute Hello world. Kiekviena eilutė "Rails" yra internacionalizuojama šiuo būdu, pvz., "Active Model" validacijos pranešimai activemodel/lib/active_model/locale/en.yml faile arba laiko ir datos formatavimas activesupport/lib/active_support/locale/en.yml faile. Galite naudoti YAML arba standartinius Ruby "Hash" objektus, kad saugotumėte vertimus numatytajame (Paprastame) pagrindiniame komponente.

"I18n" biblioteka naudos anglų kaip numatytąją lokalę, t. y. jei nėra nustatyta kita lokalė, bus naudojama :en vertimams ieškoti.

PASTABA: "I18n" biblioteka priima pragmatišką požiūrį į lokalės raktus (po kelių diskusijų), įtraukdama tik lokale ("kalba") dalį, pvz., :en, :pl, o ne regiono dalį, pvz., :"en-US" arba :"en-GB", kurios tradiciškai naudojamos atskirti "kalbas" ir "regioninius nustatymus" arba "dialektus". Daugelis tarptautinių programų naudoja tik "kalbos" elementą, pvz., :cs, :th arba :es (čekų, tajų ir ispanų kalbai). Tačiau skirtingose kalbų grupėse taip pat gali būti regioninių skirtumų, kurie gali būti svarbūs. Pavyzdžiui, :"en-US" lokalėje valiutos simbolis būtų $, o :"en-GB" - £. Nieko nekliudo jums atskirti regioninius ir kitus nustatymus šiuo būdu: tiesiog turite pateikti visą "anglų - Jungtinė Karalystė" lokalę :"en-GB" žodyne.

Vertimų kelių takas (I18n.load_path) yra kelio į failus masyvas, kurie bus automatiškai įkelti. Konfigūruojant šį taką, galima pritaikyti vertimų katalogo struktūrą ir failų pavadinimo schemą.

PASTABA: Šis pagrindinis komponentas tingiai įkelia šiuos vertimus, kai pirmą kartą ieškomas vertimas. Šį pagrindinį komponentą galima pakeisti kitu netgi po to, kai jau buvo paskelbti vertimai.

Numatytąją lokalę galite pakeisti ir konfigūruoti vertimų kelių takus config/application.rb failo pagalba:

config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')]
config.i18n.default_locale = :de

Kelių takas turi būti nurodytas prieš ieškant bet kokių vertimų. Norėdami pakeisti numatytąją lokalę iš inicializatoriaus, o ne iš config/application.rb:

# config/initializers/locale.rb

# Kur "I18n" biblioteka turėtų ieškoti vertimo failų
I18n.load_path += Dir[Rails.root.join('lib', 'locale', '*.{rb,yml}')]

# Leidžiamos lokalės, prieinamos programai
I18n.available_locales = [:en, :pt]

# Nustatyti numatytąją lokalę į kažką kitą nei :en
I18n.default_locale = :pt

Atkreipkite dėmesį, kad tiesiog pridėjus prie I18n.load_path, o ne prie programos sukonfigūruoto "I18n", vertimai iš išorinių juvelyrų nebus perrašyti.

2.2 Lokalės valdymas per užklausas

Lokalizuota programa tikriausiai turės palaikyti kelias lokales. Tam, kad tai būtų įmanoma, lokalė turėtų būti nustatoma kiekvienos užklausos pradžioje, kad visos eilutės būtų išverstos naudojant norimą lokalę per visą tos užklausos gyvavimo laikotarpį.

Numatytąją lokalę naudojama visiems vertimams, nebent naudojami I18n.locale= arba I18n.with_locale.

I18n.locale gali prasiskverbti į vėlesnes užklausas, aptarnaujamas tos pačios gijos/proceso, jei ji nėra nuosekliai nustatyta kiekviename valdiklyje. Pavyzdžiui, vykdant I18n.locale = :es vienoje POST užklausoje, tai turės poveikį visoms vėlesnėms užklausoms valdikliams, kurie nenustato lokalės, bet tik toje konkretiame gijoje/procese. Dėl šios priežasties, vietoj I18n.locale = galite naudoti I18n.with_locale, kuris neturi šio prasiskverbimo problema.

Lokalė gali būti nustatoma around_action metodu ApplicationController:

around_action :switch_locale

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

Šis pavyzdys iliustruoja, kaip tai padaryti naudojant URL užklausos parametrą nustatyti lokalę (pvz., http://example.com/books?locale=pt). Šiuo atveju, http://localhost:3000?locale=pt rodo portugalų lokalę, o http://localhost:3000?locale=de įkelia vokiečių lokalę.

Lokalė gali būti nustatoma naudojant vieną iš daugelio skirtingų būdų.

2.2.1 Lokalės nustatymas iš domeno pavadinimo

Vienas iš variantų yra nustatyti lokalę iš domeno pavadinimo, kuriame veikia jūsų programa. Pavyzdžiui, norime, kad www.example.com įkeltų anglų (ar numatytąją) lokalę, o www.example.es - ispanų lokalę. Taigi, viršutinio lygio domeno pavadinimas naudojamas lokalės nustatymui. Tai turi keletą privalumų: * Lokalė yra aiškus URL dalis. * Žmonės intuityviai supranta, kokia kalba bus rodomas turinys. * Tai labai paprasta įgyvendinti "Rails" sistemoje. * Paieškos varikliai atrodo mėgsta, kad skirtingų kalbų turinys būtų gyvena skirtingose, tarpusavyje susietose domenuose.

Galite tai įgyvendinti savo ApplicationController klasėje:

around_action :switch_locale

def switch_locale(&action)
  locale = extract_locale_from_tld || I18n.default_locale
  I18n.with_locale(locale, &action)
end

# Gauti lokalę iš viršinio lygio domeno arba grąžinti +nil+, jei tokia lokalė nėra
# Norint išbandyti tai vietiniame kompiuteryje, turite įvesti kažką panašaus į:
#   127.0.0.1 application.com
#   127.0.0.1 application.it
#   127.0.0.1 application.pl
# savo /etc/hosts faile
def extract_locale_from_tld
  parsed_locale = request.host.split('.').last
  I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil
end

Taip pat galime nustatyti lokalę iš subdomeno labai panašiu būdu:

# Gauti lokalės kodą iš užklausos subdomeno (pvz., http://it.application.local:3000)
# Norint išbandyti tai vietiniame kompiuteryje, turite įvesti kažką panašaus į:
#   127.0.0.1 gr.application.local
# savo /etc/hosts faile
def extract_locale_from_subdomain
  parsed_locale = request.subdomains.first
  I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil
end

Jei jūsų programoje yra lokalės keitimo meniu, jame turėtumėte turėti kažką panašaus:

link_to("Deutsch", "#{APP_CONFIG[:deutsch_website_url]}#{request.env['PATH_INFO']}")

tai priklauso nuo to, ar nustatysite APP_CONFIG[:deutsch_website_url] reikšmę kažkam panašiam į http://www.application.de.

Šis sprendimas turi anksčiau minėtų privalumų, tačiau galbūt negalėsite arba nenorėsite pateikti skirtingų lokalizacijų ("kalbos versijų") skirtinguose domenuose. Akivaizdus sprendimas būtų įtraukti lokalės kodą į URL parametrus (arba užklausos taką).

2.2.2 Lokalės nustatymas iš URL parametrų

Dažniausias būdas nustatyti (ir perduoti) lokalę būtų įtraukti ją į URL parametrus, kaip padarėme pirmame pavyzdyje I18n.with_locale(params[:locale], &action) around_action. Šiuo atveju norėtume turėti URL adresus kaip www.example.com/books?locale=ja arba www.example.com/ja/books.

Šis metodas turi beveik tą patį privalumų rinkinį kaip ir lokalės nustatymas iš domeno pavadinimo: t. y. tai yra RESTful ir atitinka visą Pasaulinį tinklą. Tačiau jį įgyvendinti reikia šiek tiek daugiau darbo.

Gauti lokalę iš params ir nustatyti ją atitinkamai nėra sunku; tačiau įtraukti ją į kiekvieną URL ir taip perduoti ją per užklausas yra sunkiau. Būtų nuobodu ir tikriausiai neįmanoma įtraukti aiškios parinkties į kiekvieną URL, pvz., link_to(books_url(locale: I18n.locale)).

"Rails" turi infrastruktūrą "centralizuoti dinaminius sprendimus apie URL" savo ApplicationController#default_url_options metode, kuris yra labai naudingas šiuo atveju: tai leidžia mums nustatyti "numatytuosius" url_for ir priklausančių jam pagalbinės funkcijos metodus (implementuojant/perrašant default_url_options).

Galime įtraukti kažką panašaus į savo ApplicationController:

# app/controllers/application_controller.rb
def default_url_options
  { locale: I18n.locale }
end

Kiekvienas pagalbinis metodas, priklausantis nuo url_for (pvz., pagalbiniai metodai vardintiems maršrutams, pvz., root_path arba root_url, resursų maršrutams, pvz., books_path arba books_url, ir t. t.), dabar automatiškai įtrauks lokalę į užklausos eilutę, pavyzdžiui: http://localhost:3001/?locale=ja.

Galbūt tai jums tiks. Tačiau tai daro įtaką URL skaitymui, kai lokalė "kabo" prie kiekvieno URL jūsų programoje. Be to, iš architektūrinės pusės, lokalė paprastai yra hierarchiškai aukščiau nei kitos programos srities dalys, o URL turėtų tai atspindėti.

Galbūt norite, kad URL atrodytų taip: http://www.example.com/en/books (kur įkeliamas anglų lokalė) ir http://www.example.com/nl/books (kur įkeliamas olandų lokalė). Tai pasiekiamas naudojant "perrašyti default_url_options" strategiją iš aukščiau: tiesiog turite sukonfigūruoti savo maršrutus su scope:

# config/routes.rb
scope "/:locale" do
  resources :books
end

Dabar, kai iškviečiate books_path metodą, turėtumėte gauti "/en/books" (numatytoji lokalė). URL kaip http://localhost:3001/nl/books turėtų įkelti olandų lokalę, o tolesni kvietimai į books_path turėtų grąžinti "/nl/books" (nurodyta lokalė).

ĮSPĖJIMAS. Kadangi default_url_options grąžinimo reikšmė yra talpinama keleto užklausų metu, lokalės pasirinkimoje URL negalima generuoti, iškviečiant pagalbinius metodus cikle, kuris kiekvienoje iteracijoje nustato atitinkamą I18n.locale. Vietoj to, palikite I18n.locale nepakeistą ir perduokite aiškią :locale parinktį pagalbinei funkcijai arba redaguokite request.original_fullpath.

Jei nenorite priversti naudoti lokalės savo maršrutuose, galite naudoti pasirinktinį kelio apimtį (pažymėtą skliausteliais), kaip parodyta žemiau:

# config/routes.rb
scope "(:locale)", locale: /en|nl/ do
  resources :books
end

Su šiuo požiūriu jums nebus gauta Routing Error prieigai prie jūsų išteklių, tokių kaip http://localhost:3001/books, be lokalės. Tai naudinga, kai norite naudoti numatytąją lokalę, kai nenurodyta.

Žinoma, turite ypatingai rūpintis savo programos šaknies URL (paprastai "homepage" arba "dashboard"). URL, pvz., http://localhost:3001/nl, automatiškai neveiks, nes jūsų routes.rb failo root to: "dashboard#index" deklaracija neatsižvelgia į lokalę. (Ir teisingai: yra tik vienas "root" URL.)

Jums turbūt reikės susieti tokius URL:

# config/routes.rb
get '/:locale' => 'dashboard#index'

Ypatingą dėmesį atkreipkite į savo maršrutų tvarką, kad ši maršruto deklaracija neprarytų kitų. (Galbūt norėsite ją pridėti tiesiai prieš root :to deklaraciją.)

Pastaba: Pažiūrėkite į įvairius gemus, kurie palengvina darbą su maršrutais: routing_filter, route_translator.

2.2.3 Lokalės nustatymas iš vartotojo nustatymų

Programa su autentifikuotais vartotojais gali leisti vartotojams nustatyti lokalės nustatymą per programos sąsają. Su šiuo požiūriu vartotojo pasirinkta lokalės nuostata išsaugoma duomenų bazėje ir naudojama nustatyti lokalę autentifikuotiems vartotojo užklausoms.

around_action :switch_locale

def switch_locale(&action)
  locale = current_user.try(:locale) || I18n.default_locale
  I18n.with_locale(locale, &action)
end

2.2.4 Lokalės nustatymas pagal numatytąjąją lokalę

Kai užklausai nėra nustatyta aiški lokalė (pvz., naudojant vieną iš aukščiau pateiktų metodų), programa turėtų bandyti nustatyti norimą lokalę.

2.2.4.1 Lokalės nustatymas iš kalbos antraštės

Accept-Language HTTP antraštė nurodo pageidaujamą kalbą užklausos atsakui. Naršyklės nustato šios antraštės reikšmę pagal vartotojo kalbos nustatymus, todėl tai yra geriausias pasirinkimas, kai reikia nustatyti lokalę.

Paprastas Accept-Language antraštės naudojimo įgyvendinimas būtų:

def switch_locale(&action)
  logger.debug "* Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}"
  locale = extract_locale_from_accept_language_header
  logger.debug "* Locale set to '#{locale}'"
  I18n.with_locale(locale, &action)
end

private
  def extract_locale_from_accept_language_header
    request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first
  end

Praktikoje reikalingas patikimesnis kodas, kad tai būtų padaryta patikimai. Iain Heckerio http_accept_language biblioteka arba Ryano Tomayko locale Rack middleware teikia sprendimus šiam problemos sprendimui.

2.2.4.2 Lokalės nustatymas pagal IP geolokaciją

Užklausą atliekančio kliento IP adresas gali būti naudojamas nustatyti kliento regioną ir taip nustatyti jo lokalę. Šiam požiūriui galima naudoti paslaugas, tokią kaip GeoLite2 Country arba gemus, pvz., geocoder.

Bendrai šis požiūris yra daug mažiau patikimas nei kalbos antraštės naudojimas ir nerekomenduojamas daugumai interneto programų.

2.2.5 Lokalės saugojimas iš seanso ar slapukų

ĮSPĖJIMAS: Galbūt būsite linkę saugoti pasirinktą lokalę seanse arba slapuke. Tačiau nedarykite to. Lokalė turėtų būti skaidri ir dalis URL. Taip jūs nepažeisite žmonių pagrindinių prielaidų apie patį internetą: jei siunčiate URL draugui, jis turėtų matyti tą patį puslapį ir turinį kaip ir jūs. Šiam dalykui būtų galima naudoti šiuo metu esantį žodį, kad jūs esate RESTful. Daugiau apie RESTful požiūrį galite skaityti Stefano Tilkovo straipsniuose. Kartais yra išimčių nuo šios taisyklės, apie kurias bus aptarta žemiau.

3 Tarptautinės ir vietinės reikšmės

Gerai! Dabar jūs sukonfigūravote I18n palaikymą savo Ruby on Rails programai ir pasakėte, kurią lokalę naudoti ir kaip ją išlaikyti tarp užklausų.

Toliau turime tarptautiškinti mūsų programą, pakeisdami kiekvieną lokalės specifinį elementą. Galiausiai turime vietinti ją, pateikdami būtinus vertimus šiems abstraktams.

Turint šį pavyzdį:

# config/routes.rb
Rails.application.routes.draw do
  root to: "home#index"
end
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  around_action :switch_locale

  def switch_locale(&action)
    locale = params[:locale] || I18n.default_locale
    I18n.with_locale(locale, &action)
  end
end
# app/controllers/home_controller.rb
class HomeController < ApplicationController
  def index
    flash[:notice] = "Hello Flash"
  end
end
<!-- app/views/home/index.html.erb -->
<h1>Hello World</h1>
<p><%= flash[:notice] %></p>

rails i18n demo untranslated

3.1 Abstrahuojant lokalizuotą kodą

Mūsų kode yra du anglų kalba parašyti tekstai, kurie bus atvaizduojami mūsų atsakyme ("Hello Flash" ir "Hello World"). Norint tarptautiškinti šį kodą, šie tekstai turi būti pakeisti skambučiais į Rails #t pagalbininką su tinkamu raktu kiekvienam teksto fragmentui:

# app/controllers/home_controller.rb
class HomeController < ApplicationController
  def index
    flash[:notice] = t(:hello_flash)
  end
end
<!-- app/views/home/index.html.erb -->
<h1><%= t :hello_world %></h1>
<p><%= flash[:notice] %></p>

Dabar, kai šis rodinys yra sugeneruojamas, jis parodys klaidos pranešimą, kuris jums pasakys, kad trūksta vertimų raktams :hello_world ir :hello_flash.

rails i18n demonstracinis vertimas trūksta

PASTABA: „Rails“ į savo rodinius prideda t (translate) pagalbinį metodą, todėl jums nereikia visada rašyti I18n.t. Be to, šis pagalbininkas sugauna trūkstamus vertimus ir apgaubia gautą klaidos pranešimą <span class="translation_missing"> žyma.

3.2 Suteikti vertimus tarptautinėms eilutėms

Pridėkite trūkstamus vertimus į vertimų žodyno failus:

# config/locales/en.yml
en:
  hello_world: Hello world!
  hello_flash: Hello flash!
# config/locales/pirate.yml
pirate:
  hello_world: Ahoy World
  hello_flash: Ahoy Flash

Kadangi default_locale nepasikeitė, vertimai naudoja :en lokalę ir atsakas atvaizduoja anglų kalbos eilutes:

rails i18n demonstracinis išverstas į anglų kalbą

Jei lokalė nustatyta per URL į piratinę lokalę (http://localhost:3000?locale=pirate), atsakas atvaizduoja piratų kalbos eilutes:

rails i18n demonstracinis išverstas į piratų kalbą

PASTABA: Pridėjus naujus lokalės failus, reikia paleisti serverį iš naujo.

Galite naudoti YAML (.yml) arba paprastus Ruby (.rb) failus, kad saugotumėte savo vertimus „SimpleStore“. Tarp „Rails“ programuotojų YAML yra pageidaujama parinktis. Tačiau ji turi vieną didelį trūkumą. YAML labai jautrus tarpų ir specialių simbolių vietoms, todėl programa gali neteisingai įkelti jūsų žodyną. Ruby failai gali sugriauti jūsų programą pirmo užklausos metu, todėl lengvai galite rasti, kas negerai. (Jei susiduriate su „keistais“ YAML žodynais susijusiais klausimais, bandykite įkeliant susijusią žodyno dalį į Ruby failą.)

Jei jūsų vertimai saugomi YAML failuose, tam tikri raktai turi būti išvengti. Jie yra:

  • true, on, yes
  • false, off, no

Pavyzdžiai:

# config/locales/en.yml
en:
  success:
    'true':  'True!'
    'on':    'On!'
    'false': 'False!'
  failure:
    true:    'True!'
    off:     'Off!'
    false:   'False!'
I18n.t 'success.true'  # => 'True!'
I18n.t 'success.on'    # => 'On!'
I18n.t 'success.false' # => 'False!'
I18n.t 'failure.false' # => Vertimas trūksta
I18n.t 'failure.off'   # => Vertimas trūksta
I18n.t 'failure.true'  # => Vertimas trūksta

3.3 Kintamųjų perdavimas vertimams

Vienas svarbus dalykas, siekiant sėkmingai tarptautiškai pritaikyti programą, yra vengti neteisingų prielaidų dėl gramatikos taisyklių, kai abstrahuojamas lokalizuotas kodas. Gramatikos taisyklės, kurios vienoje lokalėje atrodo pagrindinės, gali netaikytis kitose.

Netinkamas abstrahavimas parodytas šiame pavyzdyje, kai daroma prielaida dėl skirtingų vertimo dalių tvarkos. Atkreipkite dėmesį, kad „Rails“ teikia number_to_currency pagalbinį metodą, skirtą tvarkyti šį atvejį.

<!-- app/views/products/show.html.erb -->
<%= "#{t('currency')}#{@product.price}" %>
# config/locales/en.yml
en:
  currency: "$"
# config/locales/es.yml
es:
  currency: "€"

Jei produkto kaina yra 10, tada tinkamas vertimas ispanų kalba yra "10 €" vietoje "€10", bet abstrakcija to negali suteikti.

Norint sukurti tinkamą abstrakciją, „I18n“ biblioteka turi funkciją, vadinamą kintamųjų interpoliacija, kuri leidžia naudoti kintamuosius vertimo apibrėžimuose ir perduoti šių kintamųjų reikšmes vertimo metode.

Tinkamas abstrahavimas parodytas šiame pavyzdyje:

<!-- app/views/products/show.html.erb -->
<%= t('product_price', price: @product.price) %>
# config/locales/en.yml
en:
  product_price: "$%{price}"
# config/locales/es.yml
es:
  product_price: "%{price} €"

Visi gramatiniai ir skyrybos sprendimai priimami pačiame apibrėžime, todėl abstrakcija gali suteikti tinkamą vertimą.

PASTABA: „default“ ir „scope“ raktažodžiai yra rezervuoti ir negali būti naudojami kaip kintamųjų pavadinimai. Jei naudojami, iškyla I18n::ReservedInterpolationKey išimtis. Jei vertimas tikisi interpoliacijos kintamojo, bet šis nebuvo perduotas #translate, iškyla I18n::MissingInterpolationArgument išimtis.

3.4 Pridėti datos/laiko formatavimus

Gerai! Dabar pridėkime laiko žymą į rodinį, kad galėtume demonstruoti ir datos/laiko lokalizavimo funkciją. Norėdami lokalizuoti laiko formatą, perduodate laiko objektą į I18n.l arba (geriau) naudokite „Rails“ #l pagalbininką. Galite pasirinkti formatą, perduodant :format parinktį - pagal numatytuosius nustatymus naudojamas :default formatas.

<!-- app/views/home/index.html.erb -->
<h1><%= t :hello_world %></h1>
<p><%= flash[:notice] %></p>
<p><%= l Time.now, format: :short %></p>

Ir mūsų piratų vertimų faile pridėkime laiko formatą (jis jau yra „Rails“ numatytuosiuose nustatymuose anglų kalbai):

# config/locales/pirate.yml
pirate:
  time:
    formats:
      short: "arrrround %H'ish"

Tai duotų jums:

rails i18n demonstracinis laikas lokalizuotas į piratų kalbą

PATARIMAS: Šiuo metu, norint, kad I18n pagrindas veiktų kaip tikimasi (bent jau „piratų“ lokalės atveju), gali prireikti pridėti keletą daugiau datos/laiko formatų. Žinoma, yra didelė tikimybė, kad kažkas jau atliko visą darbą, išverčiant „Rails“ numatytuosius nustatymus jūsų lokalės atžvilgiu. Peržiūrėkite rails-i18n saugyklą „GitHub“ įvairių lokalės failų archyvui. Įdėjus tokius failus į config/locales/ aplanką, jie automatiškai bus pasirengę naudoti.

3.5 Lenkijos kalbos lokalizacijos taisyklės

Rails leidžia apibrėžti lokalizacijos taisykles (pvz., vienaskaitos ir daugiskaitos formavimo taisykles) kitoms nei anglų kalbai. config/initializers/inflections.rb faile galite apibrėžti šias taisykles kelioms kalboms. Inicializatorius jau turi numatytąją anglų kalbos taisyklių pavyzdį; naudokite tą formatą kitoms kalboms, kaip jums tinkama.

3.6 Lokalizuoti rodiniai

Tarkime, jūsų aplikacijoje yra BooksController. Jūsų index veiksmas atvaizduoja turinį naudojant app/views/books/index.html.erb šabloną. Kai į tą pačią direktoriją įdedate lokalizuotą variantą šio šablono: index.es.html.erb, Rails atvaizduos turinį šiame šablone, kai kalba nustatyta kaip :es. Kai kalba nustatyta kaip numatytoji kalba, bus naudojamas bendrinis index.html.erb rodinys. (Ateityje Rails versijos gali atnešti šią automatinę lokalizaciją ir kitiems public direktorijos failams ir pan.)

Galite naudoti šią funkciją, pvz., dirbdami su dideliu statiniu turiniu, kurį būtų nepatogu įdėti į YAML ar Ruby žodynus. Tačiau atkreipkite dėmesį, kad bet kokia vėlesnė šablono pakeitimo norima pakeisti visuose šablonuose.

3.7 Lokalizacijos failų organizavimas

Kai naudojate numatytąjį SimpleStore, kuris yra pristatomas su i18n biblioteka, žodynai yra saugomi tekstinėse failuose diske. Vertimams visų jūsų aplikacijos dalių saugoti viename failo viename lokalėje gali būti sunku tvarkyti. Galite saugoti šiuos failus hierarchijoje, kuri jums atrodo prasminga.

Pavyzdžiui, jūsų config/locales direktorija gali atrodyti taip:

|-defaults
|---es.yml
|---en.yml
|-models
|---book
|-----es.yml
|-----en.yml
|-views
|---defaults
|-----es.yml
|-----en.yml
|---books
|-----es.yml
|-----en.yml
|---users
|-----es.yml
|-----en.yml
|---navigation
|-----es.yml
|-----en.yml

Taip galite atskirti modelio ir modelio atributo pavadinimus nuo teksto šablonuose, ir visą tai nuo "numatytųjų" (pvz., datos ir laiko formatų). Kitos i18n bibliotekos saugyklos gali teikti skirtingus būdus tokiam atskyrimui.

PASTABA: Numatytasis kalbos įkėlimo mechanizmas Rails neatidaro kalbos failų įdėtų į įdėtus žodynus, kaip turime čia. Taigi, kad tai veiktų, turime aiškiai pasakyti Rails, kad ieškotų toliau:

# config/application.rb
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]

4 I18n API funkcijų apžvalga

Turėtumėte gerai suprasti, kaip naudoti i18n biblioteką ir žinoti, kaip tarptautiškai pritaikyti pagrindinę Rails aplikaciją. Tolimesniuose skyriuose aptarsime šių funkcijų detalesnį naudojimą.

Šiuose skyriuose bus pateikti pavyzdžiai, naudojant tiek I18n.translate metodą, tiek translate šablono pagalbinį metodą (pabrėžiant papildomas funkcijas, kurias teikia šablono pagalbinis metodas).

Bus aptariamos tokių funkcijų kaip:

  • vertimų paieška
  • duomenų interpoliavimas į vertimus
  • daugiskaitos formavimas
  • saugaus HTML vertimų naudojimas (tik šablono pagalbinis metodas)
  • datos, skaičių, valiutos ir kt. lokalizavimas

4.1 Vertimų paieška

4.1.1 Pagrindinė paieška, sritys ir įdėti raktai

Vertimai ieškomi pagal raktus, kurie gali būti tiek simboliai, tiek eilutės, todėl šie kvietimai yra ekvivalentūs:

I18n.t :message
I18n.t 'message'

translate metodas taip pat priima :scope parinktį, kuri gali turėti vieną ar daugiau papildomų raktų, kurie bus naudojami nurodyti "apribojimų" arba srities vertimo rakto:

I18n.t :record_invalid, scope: [:activerecord, :errors, :messages]

Tai ieško :record_invalid pranešimo Active Record klaidų pranešimuose.

Be to, tiek raktas, tiek sritys gali būti nurodyti taip, kaip taškais atskirti raktai, pvz.:

I18n.translate "activerecord.errors.messages.record_invalid"

Taigi šie kvietimai yra ekvivalentūs:

I18n.t 'activerecord.errors.messages.record_invalid'
I18n.t 'errors.messages.record_invalid', scope: :activerecord
I18n.t :record_invalid, scope: 'activerecord.errors.messages'
I18n.t :record_invalid, scope: [:activerecord, :errors, :messages]

4.1.2 Numatytieji vertimai

Kai yra pateikta :default parinktis, jos reikšmė bus grąžinta, jei vertimas neegzistuoja:

I18n.t :missing, default: 'Not here'
# => 'Not here'

Jei :default reikšmė yra simbolis, ji bus naudojama kaip raktas ir išversta. Galima pateikti kelias reikšmes kaip numatytąsias. Bus grąžinta pirmoji reikšmė, kuri duoda rezultatą.

Pvz., šis pirmiausia bandys išversti raktą :missing, o tada raktą :also_missing. Kadangi abu neatneša rezultato, bus grąžinta eilutė "Not here":

I18n.t :missing, default: [:also_missing, 'Not here']
# => 'Not here'

4.1.3 Daugelio vertimų paieška ir srities paieška

Norint vienu metu ieškoti kelių vertimų, galima perduoti raktų masyvą: ```ruby I18n.t [:odd, :even], scope: 'errors.messages'

=> ["turi būti nelyginis", "turi būti lyginis"]


Taip pat, raktas gali būti išverstas į (galbūt įdėtą) įdėtą išverstų vertimų hash'ą. Pvz., galima gauti _visus_ Active Record klaidų pranešimus kaip Hash su:

```ruby
I18n.t 'errors.messages'
# => {:inclusion=>"nėra sąraše", :exclusion=> ... }

Jei norite atlikti interpoliaciją su dideliu vertimų hash'u, turite perduoti deep_interpolation: true kaip parametrą. Kai turite šį žodyną:

en:
  welcome:
    title: "Sveiki!"
    content: "Sveiki atvykę į %{app_name}"

tada įdėtasis įdėjimas bus ignoruojamas be nustatymo:

I18n.t 'welcome', app_name: 'knygynas'
# => {:title=>"Sveiki!", :content=>"Sveiki atvykę į %{app_name}"}

I18n.t 'welcome', deep_interpolation: true, app_name: 'knygynas'
# => {:title=>"Sveiki!", :content=>"Sveiki atvykę į knygynas"}

4.1.4 "Tingus" paieška

Rails įgyvendina patogų būdą ieškoti vietinės kalbos vaizduose. Kai turite šį žodyną:

es:
  books:
    index:
      title: "Pavadinimas"

galite ieškoti books.index.title vertės viduje app/views/books/index.html.erb šablone taip (atsižvelgiant į tašką):

<%= t '.title' %>

PASTABA: Automatinė vertimo ribojimas pagal dalį yra galimas tik naudojant translate pagalbinės peržiūros metodą.

"Tingią" paiešką taip pat galima naudoti kontroleriuose:

en:
  books:
    create:
      success: Knyga sukurta!

Tai naudinga, pavyzdžiui, nustatant "flash" pranešimus:

class BooksController < ApplicationController
  def create
    # ...
    redirect_to books_url, notice: t('.success')
  end
end

4.2 Daugiskaita

Daugelyje kalbų - įskaitant anglų kalbą - yra tik dvi formos, vienaskaita ir daugiskaita, tam tikram žodžiui, pvz., "1 žinutė" ir "2 žinutės". Kiti kalbos (Arabų, Japonų, Rusų ir daugelis kitų) turi skirtingas gramatikas, kuriose yra papildomos arba mažiau daugiskaitos formos. Todėl I18n API suteikia lankstų daugiskaitos funkcionalumą.

:count interpoliacijos kintamasis turi ypatingą vaidmenį, nes jis tiek yra interpoliuojamas į vertimą, tiek naudojamas pasirinkti daugiskaitą iš vertimų pagal daugiskaitos taisykles, apibrėžtas daugiskaitos pagrindinėje dalyje. Pagal numatytuosius nustatymus taikomos tik anglų kalbos daugiskaitos taisyklės.

I18n.backend.store_translations :en, inbox: {
  zero: 'nėra žinučių', # neprivaloma
  one: 'viena žinutė',
  other: '%{count} žinutės'
}
I18n.translate :inbox, count: 2
# => '2 žinutės'

I18n.translate :inbox, count: 1
# => 'viena žinutė'

I18n.translate :inbox, count: 0
# => 'nėra žinučių'

Daugiskaitos algoritmas :en yra toks paprastas:

lookup_key = :zero if count == 0 && entry.has_key?(:zero)
lookup_key ||= count == 1 ? :one : :other
entry[lookup_key]

Vertimas, žymimas kaip :one, laikomas vienaskaita, o :other naudojamas daugiskaitai. Jei skaičius yra nulis ir yra :zero įrašas, jis bus naudojamas vietoj :other.

Jei raktui skirtas ieškomas vertimas negrąžina tinkamo daugiskaitos vertimo hash'o, išmetamas I18n::InvalidPluralizationData išimtis.

4.2.1 Lokalės specifinės taisyklės

I18n gem suteikia daugiskaitos pagrindinę dalį, kurią galima naudoti, kad būtų galima įjungti lokalės specifines taisykles. Įtraukite jį į paprastą pagrindinę dalį ir tada įdėkite lokalizuotas daugiskaitos algoritmus į vertimo saugyklą, kaip i18n.plural.rule.

I18n::Backend::Simple.include(I18n::Backend::Pluralization)
I18n.backend.store_translations :pt, i18n: { plural: { rule: lambda { |n| [0, 1].include?(n) ? :one : :other } } }
I18n.backend.store_translations :pt, apples: { one: 'viena arba nėra', other: 'daugiau nei viena' }

I18n.t :apples, count: 0, locale: :pt
# => 'viena arba nėra'

Alternatyviai, galima naudoti atskirą gemą rails-i18n, kad būtų galima gauti pilnesnį rinkinį lokalės specifinių daugiskaitos taisyklių.

4.3 Lokalės nustatymas ir perdavimas

Lokalė gali būti nustatoma pseudo-globaliai I18n.locale (kuris naudoja Thread.current taip pat kaip, pavyzdžiui, Time.zone) arba gali būti perduodama kaip parinktis į #translate ir #localize.

Jei nėra perduodama lokalė, naudojama I18n.locale:

I18n.locale = :de
I18n.t :foo
I18n.l Time.now

Išsami lokalės perdavimas:

I18n.t :foo, locale: :de
I18n.l Time.now, locale: :de

I18n.locale pagal numatymą yra I18n.default_locale, kuris pagal numatymą yra :en. Numatytąją lokalę galima nustatyti taip:

I18n.default_locale = :de

4.4 Saugaus HTML vertimų naudojimas

Raktai su '_html' priesaga ir pavadinimu 'html' pažymimi kaip saugūs HTML. Kai juos naudojate peržiūrose, HTML nebus išvengta.

# config/locales/en.yml
en:
  welcome: <b>sveiki!</b>
  hello_html: <b>labas!</b>
  title:
    html: <b>pavadinimas!</b>
<!-- app/views/home/index.html.erb -->
<div><%= t('welcome') %></div>
<div><%= raw t('welcome') %></div>
<div><%= t('hello_html') %></div>
<div><%= t('title.html') %></div>

Interpoliacija bėga pagal poreikį. Pavyzdžiui, turint:

en:
  welcome_html: "<b>Sveiki, %{username}!</b>"

galite saugiai perduoti vartotojo nustatytą vartotojo vardą:

<%# Tai saugu, jei reikia, tai bus išvengta. %>
<%= t('welcome_html', username: @current_user.username) %>

Saugūs tekstai, kita vertus, yra interpoliuojami tiesiogiai.

PASTABA: Automatinis konvertavimas į HTML saugų išverstą tekstą yra galimas tik naudojant translate (arba t) pagalbinę metodą. Tai veikia rodiniuose ir valdikliuose.

i18n demo HTML saugus

4.5 Verčiamosios žinutės aktyviems įrašų modeliams

Galite naudoti metodus Model.model_name.human ir Model.human_attribute_name(attribute), kad automatiškai ieškotumėte vertimų savo modelio ir atributo pavadinimams.

Pavyzdžiui, pridėjus šiuos vertimus:

en:
  activerecord:
    models:
      user: Klientas
    attributes:
      user:
        login: "Vartotojo vardas"
      # User atributas "login" bus išverstas kaip "Vartotojo vardas"

Tada User.model_name.human grąžins "Klientas", o User.human_attribute_name("login") grąžins "Vartotojo vardas".

Taip pat galite nustatyti daugiskaitos formą modelio pavadinimams, pridėdami šiuos vertimus:

en:
  activerecord:
    models:
      user:
        one: Klientas
        other: Klientai

Tada User.model_name.human(count: 2) grąžins "Klientai". Su count: 1 arba be parametrų grąžins "Klientas".

Jei reikia pasiekti įdėtus atributus tam tikrame modelyje, turėtumėte įdėti juos po model/attribute modelio lygyje savo vertimo faile:

en:
  activerecord:
    attributes:
      user/role:
        admin: "Administratorius"
        contributor: "Prisidėjėjas"

Tada User.human_attribute_name("role.admin") grąžins "Administratorius".

PASTABA: Jei naudojate klasę, kuri įtraukia ActiveModel ir nėra paveldima iš ActiveRecord::Base, pakeiskite activerecord į activemodel aukščiau pateiktuose raktų takuose.

4.5.1 Klaidų žinučių sritys

Aktyvių įrašų validacijos klaidų žinutės taip pat gali būti lengvai išverčiamos. Aktyvusis įrašas suteikia keletą sričių, kuriose galite įdėti savo žinučių vertimus, kad galėtumėte pateikti skirtingas žinutes ir vertimus tam tikriems modeliams, atributams ir/arba validacijoms. Taip pat tai skaidriai atsižvelgia į vieno lentelės paveldėjimo.

Tai suteikia gana galingus būdus lankstamai pritaikyti savo žinutes pagal jūsų programos poreikius.

Pagalvokite apie vartotojo modelį su validacija vardo atributui, pavyzdžiui:

class User < ApplicationRecord
  validates :name, presence: true
end

Klaidos žinutės raktas šiuo atveju yra :blank. Aktyvusis įrašas ieškos šio rakto šiose srityse:

activerecord.errors.models.[modelio_pavadinimas].attributes.[atributo_pavadinimas]
activerecord.errors.models.[modelio_pavadinimas]
activerecord.errors.messages
errors.attributes.[atributo_pavadinimas]
errors.messages

Taigi, mūsų pavyzdyje jis išbandys šiuos raktus šia tvarka ir grąžins pirmą rezultatą:

activerecord.errors.models.user.attributes.name.blank
activerecord.errors.models.user.blank
activerecord.errors.messages.blank
errors.attributes.name.blank
errors.messages.blank

Kai jūsų modeliai taip pat naudoja paveldėjimą, tada žinutės ieškomos paveldėjimo grandinėje.

Pavyzdžiui, gali būti, kad turite administratoriaus modelį, paveldintį iš vartotojo:

class Admin < User
  validates :name, presence: true
end

Tada aktyvusis įrašas ieškos žinučių šia tvarka:

activerecord.errors.models.admin.attributes.name.blank
activerecord.errors.models.admin.blank
activerecord.errors.models.user.attributes.name.blank
activerecord.errors.models.user.blank
activerecord.errors.messages.blank
errors.attributes.name.blank
errors.messages.blank

Taip galite pateikti specialius vertimus įvairioms klaidų žinutėms skirtinguose jūsų modelio paveldėjimo grandinės taškuose ir atributuose, modeliuose ar numatytuose taikiniuose.

4.5.2 Klaidų žinučių interpoliacija

Išverstas modelio pavadinimas, išverstas atributo pavadinimas ir reikšmė visada yra prieinami interpoliacijai kaip model, attribute ir value atitinkamai.

Taigi, pavyzdžiui, vietoj numatytosios klaidos žinutės "negali būti tuščias" galėtumėte naudoti atributo pavadinimą taip: "Prašome užpildyti %{attribute}".

  • count, jei yra, gali būti naudojamas daugiskaitos formavimui:
validacija su parinktimi žinutė interpoliacija
confirmation - :confirmation attribute
acceptance - :accepted -
presence - :blank -
absence - :present -
length :within, :in :too_short count
length :within, :in :too_long count
length :is :wrong_length count
length :minimum :too_short count
length :maximum :too_long count
uniqueness - :taken -
format - :invalid -
inclusion - :inclusion -
exclusion - :exclusion -
associated - :invalid -
non-optional association - :required -
numericality - :not_a_number -
numericality :greater_than :greater_than count
numericality :greater_than_or_equal_to :greater_than_or_equal_to count
numericality :equal_to :equal_to count
numericality :less_than :less_than count
numericality :less_than_or_equal_to :less_than_or_equal_to count
numericality :other_than :other_than count
numericality :only_integer :not_an_integer -
numericality :in :in count
numericality :odd :odd -
numericality :even :even -
comparison :greater_than :greater_than count
comparison :greater_than_or_equal_to :greater_than_or_equal_to count
comparison :equal_to :equal_to count
comparison :less_than :less_than count
comparison :less_than_or_equal_to :less_than_or_equal_to count
comparison :other_than :other_than count

4.6 Veiksmų laiško el. pašto temų vertimai

Jei mail metodui neperduodate temos, Action Mailer bandys ją rasti jūsų vertimų failuose. Ieškoma pagal šabloną <mailer_scope>.<action_name>.subject, kad būtų sudarytas raktas.

# user_mailer.rb
class UserMailer < ActionMailer::Base
  def welcome(user)
    #...
  end
end
en:
  user_mailer:
    welcome:
      subject: "Sveiki atvykę į „Rails Guides“!"

Norėdami perduoti parametrus interpoliacijai, naudokite default_i18n_subject metodą laiškų siuntiklyje.

# user_mailer.rb
class UserMailer < ActionMailer::Base
  def welcome(user)
    mail(to: user.email, subject: default_i18n_subject(user: user.name))
  end
end
en:
  user_mailer:
    welcome:
      subject: "%{user}, sveiki atvykę į „Rails Guides“!"

4.7 Kitų įdiegtų metodų, kurie palaiko tarptautinę lokalizaciją, apžvalga

Rails naudoja fiksuotus tekstus ir kitas lokalizacijas, pvz., formatavimo tekstus ir kitą formatavimo informaciją, kai kuriose pagalbinėse funkcijose. Štai trumpas apžvalga.

4.7.1 Action View pagalbos metodai

  • distance_of_time_in_words išverčia ir daugiskaitina rezultatą ir interpoliuoja sekundžių, minučių, valandų ir t.t. skaičių. Žr. datetime.distance_in_words vertimus.

  • datetime_select ir select_month naudoja išverstus mėnesių pavadinimus, kad užpildytų rezultatą sukuriantį pasirinkimo žymės žymą. Žr. date.month_names vertimus. datetime_select taip pat ieško tvarkos parinkties iš date.order (jei jos nenurodytumėte). Visi datos pasirinkimo pagalbiniai metodai išverčia pranešimą naudodami vertimus iš datetime.prompts srities, jei taikoma.

  • number_to_currency, number_with_precision, number_to_percentage, number_with_delimiter ir number_to_human_size pagalbos metodai naudoja skaičių formato nustatymus, esančius number srityje.

4.7.2 Active Model metodai

  • model_name.human ir human_attribute_name naudoja modelio ir atributo pavadinimų vertimus, jei jie yra activerecord.models srityje. Jie taip pat palaiko paveldėtų klasės pavadinimų vertimus (pvz., naudojant STI), kaip paaiškinta aukščiau „Klaidų pranešimų sritys“ skyriuje.

  • ActiveModel::Errors#generate_message (kurį naudoja Active Model validacijos, bet jį galima naudoti ir rankiniu būdu) naudoja model_name.human ir human_attribute_name (žr. aukščiau). Jis taip pat išverčia klaidos pranešimą ir palaiko paveldėtų klasės pavadinimų vertimus, kaip paaiškinta aukščiau „Klaidų pranešimų sritys“ skyriuje.

  • ActiveModel::Error#full_message ir ActiveModel::Errors#full_messages prideda atributo pavadinimą prie klaidos pranešimo naudodami formatą, kurį ieško errors.format (numatytasis: "%{attribute} %{message}"). Norėdami tinkinti numatytąjį formatą, perrašykite jį programos lokalizacijos failuose. Norėdami tinkinti formatą pagal modelį ar atributą, žr. config.active_model.i18n_customize_full_message.

4.7.3 Active Support metodai

  • Array#to_sentence naudoja formatavimo nustatymus, kaip nurodyta support.array srityje.

5 Kaip saugoti savo tinkintus vertimus

Aktyviojo palaikymo pristatomas paprastas pagrindas leidžia saugoti vertimus tiek paprastame Ruby, tiek YAML formate.2

Pavyzdžiui, Ruby Hash, kuris teikia vertimus, gali atrodyti taip:

{
  pt: {
    foo: {
      bar: "baz"
    }
  }
}

Atitinkamas YAML failas atrodytų taip:

pt:
  foo:
    bar: baz

Kaip matote, abiem atvejais viršutinis lygio raktas yra lokalė. :foo yra srities raktas, o :bar yra vertimo „baz“ raktas.

Čia yra „realus“ pavyzdys iš Active Support en.yml vertimų YAML failo:

en:
  date:
    formats:
      default: "%Y-%m-%d"
      short: "%b %d"
      long: "%B %d, %Y"

Taigi, visi šie ekvivalentūs paieškos rezultatai grąžins :short datos formatą "%b %d":

I18n.t 'date.formats.short'
I18n.t 'formats.short', scope: :date
I18n.t :short, scope: 'date.formats'
I18n.t :short, scope: [:date, :formats]

Bendrai rekomenduojame naudoti YAML kaip formatą vertimams saugoti. Tačiau yra atvejų, kai norite saugoti Ruby lambda funkcijas kaip savo lokalės duomenų dalį, pvz., specialiems datos formatams.

6 Tinkinkite savo I18n konfigūraciją

6.1 Naudodami kitus pagrindus

Dėl kelių priežasčių Aktyviojo palaikymo pristatomas paprastas pagrindas veikia tik „paprastiausią įmanomą veiksmą“ Ruby on Rails atveju3 ... tai reiškia, kad jis garantuotai veikia tik anglų kalbai ir, kaip šalutinis efektas, kalboms, labai panašioms į anglų kalbą. Be to, paprastas pagrindas gali tik skaityti vertimus, bet negali dinamiškai juos saugoti jokiai formai.

Tai nereiškia, kad esate suvaržytas šiomis ribomis. Ruby I18n biblioteka labai lengvai leidžia pakeisti paprasto pagrindo įgyvendinimą kitu, kuris geriau tinka jūsų poreikiams, perduodant pagrindo egzempliorių į I18n.backend= setterį.

Pavyzdžiui, galite pakeisti paprastą pagrindą grandinės pagrindu, kad sujungtumėte kelis pagrindus. Tai naudinga, kai norite naudoti standartinius vertimus su paprastu pagrindu, bet savo programos tinkintus vertimus saugoti duomenų bazėje ar kituose pagrinduose. Su Chain backendu galite naudoti Active Record backendą ir grįžti prie (numatytojo) Simple backendo:

I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)

6.2 Naudoti skirtingus išimčių tvarkytojus

I18n API apibrėžia šias išimtis, kurios bus iškeliamos backendams, kai atsiranda atitinkamos netikėtos sąlygos:

Išimtis Priežastis
I18n::MissingTranslationData nebuvo rasta vertimo užklausta raktui
I18n::InvalidLocale nustatytas I18n.locale lokalė yra netinkama (pvz., nil)
I18n::InvalidPluralizationData buvo perduotas skaičiaus parinktis, bet vertimo duomenys netinka daugiskumui
I18n::MissingInterpolationArgument vertimas tikisi interpolacijos argumento, kuris nebuvo perduotas
I18n::ReservedInterpolationKey vertime yra rezervuotas interpolacijos kintamojo pavadinimas (t.y. vienas iš: scope, default)
I18n::UnknownFileType backendas nežino, kaip tvarkyti failo tipą, kuris buvo pridėtas prie I18n.load_path

6.2.1 Individualaus I18n::MissingTranslationData tvarkymo pritaikymas

Jei config.i18n.raise_on_missing_translations yra true, bus iškeliamos I18n::MissingTranslationData klaidos. Gerai būtų tai įjungti savo testavimo aplinkoje, kad galėtumėte pastebėti vietose, kuriose reikalingi vertimai yra prarasti.

Jei config.i18n.raise_on_missing_translations yra false (numatytoji reikšmė visose aplinkose), bus spausdinamas išimties klaidos pranešimas. Jame bus nurodytas praleistas raktas/sritis, kad galėtumėte ištaisyti savo kodą.

Jei norite toliau pritaikyti šį elgesį, turėtumėte nustatyti config.i18n.raise_on_missing_translations = false ir tada įgyvendinti I18n.exception_handler. Individualus išimčių tvarkytojas gali būti proc arba klasė su call metodu:

# config/initializers/i18n.rb
module I18n
  class RaiseExceptForSpecificKeyExceptionHandler
    def call(exception, locale, key, options)
      if key == "special.key"
        "translation missing!" # grąžinti tai, o ne iškelti
      elsif exception.is_a?(MissingTranslation)
        raise exception.to_exception
      else
        raise exception
      end
    end
  end
end

I18n.exception_handler = I18n::RaiseExceptForSpecificKeyExceptionHandler.new

Tai iškeltų visas išimtis taip pat, kaip tai padarytų numatytasis tvarkytojas, išskyrus atvejį, kai I18n.t("special.key").

7 Modelio turinio vertimas

Šiame vadove aprašytas I18n API yra skirtas pagrindinai sąsajos eilutėms vertinti. Jei norite versti modelio turinį (pvz., tinklaraščio įrašus), jums reikės kitokios sprendimo, kad tai padėtų.

Kelių gemų gali padėti su tuo:

  • Mobility: Suteikia palaikymą vertimų saugojimui įvairiais formatais, įskaitant vertimų lentelės, JSON stulpelių (PostgreSQL) ir kt.
  • Traco: Verčiamos kolonos saugomos paties modelio lentelėje

8 Išvada

Šiuo metu turėtumėte turėti gera apžvalgą apie tai, kaip Ruby on Rails I18n palaikymas veikia ir esate pasiruošę pradėti vertinti savo projektą.

9 Indėlis į Rails I18n

I18n palaikymas Ruby on Rails buvo įvestas 2.2 versijoje ir vis dar tobulėja. Projektas seka gerą Ruby on Rails plėtros tradiciją, kurioje sprendimai evoliucionuoja pirmiausia gemuose ir tik tada yra pasirenkami geriausiai tinkami ir plačiai naudojami funkcijų branduolyje.

Todėl mes skatiname visus eksperimentuoti su naujomis idėjomis ir funkcijomis gemuose ar kitose bibliotekose ir padaryti jas prieinamas bendruomenei. (Nepamirškite pranešti apie savo darbą mūsų pašto sąraše!)

Jei jūsų pačių lokalė (kalba) trūksta mūsų pavyzdinių vertimų duomenų saugykloje Ruby on Rails, prašome fork saugyklą, pridėkite savo duomenis ir siųskite pull request.

10 Šaltiniai

11 Autoriai

12 Šaltiniai(fixed)

1 Arba, cituojant Wikipedia: "Internationalization is the process of designing a software application so that it can be adapted to various languages and regions without engineering changes. Localization is the process of adapting software for a specific region or language by adding locale-specific components and translating text."

2 Kiti backendai gali leisti arba reikalauti naudoti kitus formatus, pvz., GetText backendas gali leisti skaityti GetText failus.

3 Viena iš šių priežasčių yra ta, kad nenorime įtraukti nereikalingo krūvio programoms, kurios nereikalauja jokių I18n galimybių, todėl I18n biblioteką turime laikyti kuo paprasčiausią anglų kalbai. Kitas priežastis yra tai, kad praktiškai neįmanoma įgyvendinti vieno sprendimo visiems egzistuojantiems kalboms susijusiems su I18n problemoms. Taigi sprendimas, leidžiantis lengvai keisti visą įgyvendinimą, vis tiek yra tinkamas. Tai taip pat labai palengvina eksperimentavimą su individualiomis funkcijomis ir plėtiniais.

Atsiliepimai

Jūs esate skatinami padėti pagerinti šio vadovo kokybę.

Prašome prisidėti, jei pastebite rašybos klaidų ar faktinių klaidų. Norėdami pradėti, galite perskaityti mūsų dokumentacijos prisidėjimo skyrių.

Taip pat gali būti nepilnos informacijos arba informacijos, kuri nėra atnaujinta. Prašome pridėti bet kokią trūkstamą dokumentaciją pagrindiniam. Patikrinkite Edge vadovus pirmiausia, ar problemas jau išspręsta arba ne pagrindinėje šakoje. Patikrinkite Ruby on Rails vadovų gaires dėl stiliaus ir konvencijų.

Jei dėl kokios nors priežasties pastebite kažką, ką reikia ištaisyti, bet negalite patys tai pataisyti, prašome pranešti apie problemą.

Ir galiausiai, bet ne mažiau svarbu, bet koks diskusijos dėl Ruby on Rails dokumentacijos yra labai laukiamos oficialiame Ruby on Rails forume.