wtorek, 20 stycznia 2009

[Rails] i18n, tłumaczenia, model, globalize2

[Rails >= 2.2.2]
Railsy dostarczają bardzo prosty a zarazem bardzo przydatny mechanizm i18n służący do tworzenia różnych wersji językowych. Na początku zainstalujemy sobie plugin globalize2.

./script/plugin install git://github.com/joshmh/globalize2.git

Dzięki temu teraz w modelu możemy określić jakie pola będziemy poddawać tłumaczeniom (translates), ale o tym za chwile.

Na wstępie skonfigurujmy sobie i18n. Konfiguracja odbywa się w pliku: config/enviroment.rb. Przejdźmy do linii 50, odkomentujmy ją usuwając "#"

jeśli linia u Was tak wygląda tak:

Config.i18n.load_path << Dir[File.join(RAILS_ROOT, 'my', 'locales', '*.{rb,yml}')]

to zmieńcie ją na:

Config.i18n.load_path += Dir[File.join(RAILS_ROOT, 'my', 'locales', '*.{rb,yml}')]

Odkomentujmy jeszcze 51 linię i ustawmy domyślny język strony na polski:

config.i18n.default_locale = :pl


[zrestarujmy aplikację]

Teraz zajmiemy się plikiem migracyjnym.
Utworzymy tabele z jakimiś regionami.

class CreateRegions < ActiveRecord::Migration
def self.up
create_table :regions do |t|
t.column :value, :integer, :null => false #jakąś wartość tutaj będziemy trzymać
end

#tabela z tłumaczeniami, nazwa jest bardzo ważna musi się kończyć na _translations
create_table :region_translations do |t|
t.string :locale #tutaj się określa język, 'pl', 'en', etc.
t.references :region #odwołanie do tabeli region kolumna region_id
t.string :name, :null => false, :limit => 50
end

#importujemy przykładowe dane
Region.create(:id => 1, :value => 123)
#dodajemy tlumaczenia
RegionTranslation.create(:locale => 'pl', :region_id => 1, :name => 'region polski')
RegionTranslation.create(:locale => 'en', :region_id => 1, :name => 'region angielski')

end

def self.down
drop_table :regions
drop_table :region_translations
end
end


Importujemy:

rake db:migrate

Przechodzimy do modelu Models/region.rb

class Region < ActiveRecord::Base
end


dodajemy translates:

class Region < ActiveRecord::Base
translates :name #jaka kolumna jest poddawana tłumaczeniom
end


To by było na tyle :) użyjmy teraz tego mechanizmu:

#Zapis:
I18n.locale = 'en' #ustawiamy jaki język chcemy
r = Region.new
r.id = 19
r.value = 'cos'
r.name = 'nazwa po angielsku'
r.save

#Select:
I18n.locale = 'en'
r = Region.find_by_id 19
p r.name #wypisze'nazwa po angielsku'


Jeśli chcemy zmienić język wystarczy przestawić I18n.locale = 'pl' :) czy można prościej?

Ustawmy jeszcze w kontrolerze, by za każdym razem przeprowadzał sprawdzenie jaki język chcemy.

plik: app/controllers/application.rb


dodajemy

before_filter :set_locale

def set_locale
session[:locale] = params[:locale] if params[:locale]

I18n.locale = session[:locale] || I18n.default_locale
end


Dopiszmy w config/routes.rb :locale do routingów
:controller/:action/:id' zamieniamy na :locale/:controller/:action/:id'

No i super nasz model może zawierać kilka wersji językowych, lecz co ze statycznymi tekstami na stronie? Typu:

app/views/home.erb:

<%= 'Cześć, witaj na mojej stronie :)' =>

Jak to zmienić na język angielski? Myślę że prościej na świecie się już na prawdę nie da.
Idziemy do katalogu: config/locales tworzymy tam 2 pliki, en.yml oraz pl.yml (zawierać będą tłumaczenia).

Na pierwszy ogień bierzemy pl.yml
pl:
home:
hello: "Cześć, witaj na mojej stronie :)"


a w en.yml wpisujemy
pl:
home:
hello: "Hi, welcome to my page :)"


przechodzimy z powrotem do app/views/home.erb i zmieniamy:

<%= 'Cześć, witaj na mojej stronie :)' =>

na

<%= t 'home.hello' =>

I wszystko działa jak należy :) Magia railsów ;)

15 komentarzy:

Ris pisze...

Wydawało się mi, że w Rails się robi prosto :)

Laziers pisze...

nie no w railsach nie robi sie tego prosto, robi sie to banalnie :) #flamewar >:]

Ris pisze...

Właśnie widzę :D na załączonym wpisie :)

Laziers pisze...

a w czym sie robi to prosciej? tlumaczenia modelu oraz statycznego textu na stronie?

Ris pisze...

JSF

Laziers pisze...

chcialbym to widziec :) zamiesc odpis i wrzuc linka, porownamy

Anonimowy pisze...

temat ciekawy ale post po wnikliwszym czytaniu i późniejszej probie napisania tego kawałka kodu to już problem. za duzo skrotow myslowych po prostu

Amelia pisze...

Czekam na następny wpis.

Martyna pisze...

To jeden z lepszych blogów na blogspocie.

Anonimowy pisze...

Trafnie.

Biuro podatkowe warszawa pisze...

To jeden z lepszych blogów na blogspocie.

Prawnik Poznań pisze...

Trafnie.

Grzałki pisze...

Nie mogę spać, więc znalazłam twojego bloga, super

Fryzjer Lublin pisze...

Ten blog posiada dużo ciekawych artykułów

M1l05z pisze...

znalazłem mały błąd:

a w en.yml wpisujemy

pl: # powinno chyba być en:
home:
hello: "Hi, welcome to my page :)"