En breve me pondré con el desarrollo de un site que necesitará estar disponible en varios idiomas, así que como me apetecía investigar el tema del desarrollo de plugins en RoR, decidí hacerme uno que me solucionase la papeleta siendo totalmente consciente de estar reinventando la rueda, ya que ya existen soluciones más que probadas como Globalize o Gettext, pero el caso era cacharrear, y la verdad es que he aprendido unas cuantas cosillas sobre la programación dinámica en Ruby, así que creo que a veces vale la pena repetir cosas, al menos cuando se está aprendiendo.
De momento ya trabaja con textos estáticos(en formato yaml) y con los modelos, aunque esta parte es algo rudimentaria. He subido el código a un repositorio de subversion y para instalarlo en la aplicación basta con teclear
script/plugin install http://svn.dagi3d.net/rails/wahrig/tags/wahrig-0.1.0/
Para que el plugin funcione con un modelo, tan sólo hay que llamar al método ‘acts_as_translatable’ junto con los nombres de los campos que queremos que sean ‘traducibles’ mientras que cada uno de estos campos deberá tener su correspondiente texto traducido para las ‘locales’ que queramos tener. Y para cambiar de locale, hay que llamar a ResourceBundle.set_locale(
app/models/foo.rb
class Foo < ActiveRecord::Base
acts_as_translatable :bar
end
test/fixtures/foos.yml
foo1:
id: 1
bar: ejemplo
bar_en_US: example
bar_de_DE: Beispiel
vendor/plugins/wahrig/test/wahrig_test.rb
require File.dirname(__FILE__) + '/../../../../test/test_helper'
class WahrigTest < Test::Unit::TestCase
fixtures :foos
def test_model
foo = Foo.find(1)
assert_equal foo.bar, 'ejemplo'
ResourceBundle.set_locale('en_US')
assert_equal @foo.bar, 'example'
ResourceBundle.set_locale('de_DE')
assert_equal @foo.bar, 'Beispiel'
end
end
Para utilizarlo en el controlador para usar textos estáticos basta con llamar al método ‘act_as_translator’, y luego llamar a ‘load_bundle’ en el método que queramos dentro del controlador, indicando el nombre del fichero yaml, la variable a la que queremos asignar el contenido y la locale que queremos utilizar:
app/controllers/foo_controller.rb
class FooController < ApplicationController
acts_as_translator
def index
load_bundle("test", :foo, 'es_ES')
end
end
config/test.es_ES.yml
foo: foo - español
bar: bar - español
config/test.en_US.yml
foo: foo - english
bar: bar - english
Esto lo que haría sería cargar el fichero RAILS_ROOT/config/test.es_ES.yml y asignarle el contenido a la variable @foo, pudiendo acceder desde la vista a todos los campos definidos en el fichero:
app/views/foo/index.rhtml
<%= @foo['foo'] %>
<%= @foo['bar'] %>