Este es el post número 5 de la serie de Ruby on Rails creada por Sergio Márquez.

i18n ruby con rails

En nuestro post anterior, vimos como funcionan las rutas, como se comunican las capas del modelo MVC, convención sobre configuración y otros temas que son indispensables para entender como funciona el framework y que no todo parezca que sucede por arte de magia.

En esta oportunidad aprenderemos a crear un sitio multi-idioma con Ruby on Rails y rails-i18n. Esto último es una gema que viene incluida en el core de Rails, por lo cual no es necesario agregarla a nuestro Gemfile. Para verificarla, iremos a la consola de Rails, sí, leyeron bien, el framework incluye una poderosa herramienta que nos será de mucha ayuda al momento del desarrollo. Pero antes de abrir la consola incluiremos un par de gemas que le agregarán esteroides:

  1. Primero recuerden situarse en la carpeta del proyecto, ej: my-first-app/
  2. Luego con su editor favorito van a abrir el archivo Gemfile
  3. Por último agreguen estas líneas al archivo:
group :development do
 gem 'pry-rails'
 gem 'awesome_print'
end
  1. Luego en la terminal siempre dentro de my-first-app, ejecuten:
bundle install
  1. Una vez que el proceso haya finalizado, ejecutamos (en la terminal)
bundle exec rails console

Deberíamos ver esto en la terminal :)

[1] pry(main)>

Al haber instalado pry-rails, tendremos una serie de comandos que nos harán la vida más simple, como show-routes y show-models, para visualizar las rutas y los modelos, respectivamente.

Bueno luego de este preámbulo, retomemos el tema que veníamos desarrollando, ya dentro de la consola podemos visualizar los locales (archivos de traducciones) disponibles, ejecutamos:

I18n.available_locales
#lo cual nos debería mostrar sólo 
[:en]

Lo que quiere decir que existe sólo esa opción de «traducción» disponible, pero ¿En donde está eso?, tranquilos, no hay ninguna magia extraña detrás de esto, recuerden la entrada anterior donde hablamos sobre la filosofía de Rails, que se basa en la convención sobre configuración, y para entender mejor esto, con nuestro editor de texto naveguemos hasta el archivo: config/application.rb  y veamos la linea 19 (casi al final del archivo), encontraremos lo siguiente:

 # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.

Nota: pueden tipear «exit» para salir de la consola de Rails y «bundle exec rails console» para volver a abrirla
Lo anterior nos indica que el locale (opción de traducción) por defecto es :en y que todos los archivos que se encuentren dentro de config/locales/* estarán disponibles automáticamente. Ahora naveguemos hasta dicho directorio, efectivamente encontraremos el archivo en.yml. Abramos dicho archivo para ver que contiene:

# Files in the config/locales directory are used for internationalization
# and are automatically loaded by Rails. If you want to use locales other
# than English, add the necessary files in this directory.
#
# To use the locales, use `I18n.t`:
#
#     I18n.t 'hello'
#
# In views, this is aliased to just `t`:
#
#     <%= t('hello') %>
#
# To use a different locale, set it with `I18n.locale`:
#
#     I18n.locale = :es
#
# This would use the information in config/locales/es.yml.
#
# To learn more, please read the Rails Internationalization guide
# available at http://guides.rubyonrails.org/i18n.html.

en:
  hello: "Hello world"

Como podemos ver, es un corolario de lo anterior, junto con las instrucciones para poder utilizarlas, volvamos a nuestra consola de Rails.

bundle exec rails console

una vez dentro ejecutamos lo que nos indican las instrucciones del archivo.

[6] pry(main)> I18n.t 'hello'
"Hello world"

Ahora hagamos otro cambio modifiquemos un poco el archivo de nuestro locale (:en), para que entendamos como funciona realmente, para eso abramos el archivo config/locales/en.yml y vamos a hacer unos pequeños cambios.

  hello:
    short:    'welcome'
    long:     'Welcome to our website'
    too_long: 'Hi, welcome to our amazing website :-)'

Volvamos a la consola de Rails, escribamos «reload!» y luego nuevamente I18n.t ‘hello’

[21] pry(main)> reload! # para recargar los cambios que hemos realizado previamente
Reloading...
true
[22] pry(main)> I18n.t('hello')
{
  :short    => "wellcome",
  :long     => "Wellcome to website",
  :too_long => "Hi, welcome to our amazing website"
}
[23] pry(main)>

Como podemos ver, al querer obtener la traducción para nuestra clave :hello, ahora obtenemos un objeto (Hash), a esta altura se estarán preguntando como podemos obtener las traducciones de forma clara, bueno ahora vamos a responder esto, atentos, volvamos nuevamente a la consola:

[23] pry(main)> I18n.t('hello.short')
"wellcome"
[24] pry(main)> I18n.t('hello.long')
"Wellcome to website"
[25] pry(main)> I18n.t('hello.too_long')
"Hi, welcome to our amazing website :)"
[26] pry(main)>

Como se habrán dado cuenta, es muy sencillo acceder a los objetos anidados dentro de nuestro archivo de traducciones, solo separando las claves por punto dentro de un String.

Muy bien, ahora vamos a aplicar este tema a nuestra aplicación, para ello vamos a editar las rutas y a agregar un parámetro para setear el lenguaje a nuestro sitio, para eso vamos al archivo config/routes.rb, y vamos a reemplazar resources :posts, con el código a continuación:

Rails.application.routes.draw do
  scope '/(:locale)', defaults: { locale: 'en' }, constraints: { locale: /en|es/ } do
    resources :posts

    get '/', to: 'welcome#index'
  end
end

Lo que acabamos de hacer es definir un scope, con un parámetro :locale, que es opcional, definiendo un default (en) y restringiéndolo sólo a («es» o «en»), lo cual quiere decir que si no pasamos el parámetro, el lenguaje del sitio será inglés y sólo soportara español e inglés, para poder ver en acción lo que acabamos de hacer, vamos ir a la terminal si están aún en la consola de Rails, vamos a ejecutar:

exit

Para salir y luego:

bundle exec rails server

Para levantar el servidor, nos dirigimos a http://localhost:3000/ en nuestro navegador, como podrán ver no ha pasado nada, si visitamos http://localhost:3000/es, seguimos viendo lo mismo, pero ahora finalmente vamos a:

Editar nuestra aplicación para que sea multi-idioma

Vamos a comenzar agregando las traducciones, para eso vamos nuevamente a localizar el archivo config/locales/en.yml, debe quedar como se ve a continuación.

en:
  site_title: 'This is the english version'
  site_name: 'My Site'
  welcome: 'Wellcome to our amazing website'

Ahora en el mismo nivel (config/locales), crearemos el archivo es.yml, para las traducciones en español e incluiremos lo siguiente:

es:
  site_title: 'Esta es la versión en español'
  site_name: 'Mi sitio'
  welcome: 'Bienvenido a nuestro maravilloso sitio web'

Ahora haremos un pequeño cambio en el controlador principal, app/controllers/application_controller.rb:

before_action :set_locale

def set_locale
  I18n.locale = params[:locale].to_sym
end

Lo que hicimos fue definir un método para setear el locale de I18n de acuerdo al parámetro locale que definimos en nuestro archivo de rutas y además lo agregaremos a uno de los callbacks que nos provee Rails, para ejecutarlo antes de cada action y como todos nuestros controladores heredan de ApplicationController, este método será ejecutado antes de cada petición enviada por los usuarios en todo el sistema.

Por último nos queda poder editar nuestras vistas, lo primero que haremos es editar el layout para definir el título que se mostrará en cada una de las páginas que visite el usuario, por lo cual iremos a views/layouts/application.html.erb, localizaremos el tag title y lo reemplazaremos por esto.

<%= t('site_title')%> | <%= t('site_name')%>

Ya que hemos editado nuestro layout, es hora de editar la vista home, de nuestro sitio para que nos muestre lo que corresponde de acuerdo a la petición de nuestros usuarios, para eso vamos a views/welcome/index.html.erb y vamos a reemplazar el contenido por esto.

<%= t('welcome')%>

¡Excelente! ahora vamos a nuestro navegador y visitamos http://localhost:3000/ si todo nos ha resultado bien, podremos ver la versión en Inglés de nuestro sitio web. Ahora para ver la versión en español, volvamos a nuestro navegador y visitamos http://localhost:3000/es

Maravillo, ¿no?, pues bien, rails-i18n, no sólo nos provee las traducciones, sino que también podemos localizar la visualización de las fechas de forma simple y clara, reemplacen sus locales, con este contenido en.yml y es.yml. Finalmente, editaremos nuevamente nuestro archivo views/welcome/index.html.erb y agregaremos lo siguiente.

<%= l(Time.now, format: :long)%>

Muy bien ahora vamos a ir nuevamente a nuestro navegador, refrescaremos la página y podrán ver como aparece la fecha de acuerdo al idioma del sitio.

Espero que hayan disfrutado de este tutorial, si hay algo que no entendieron, me pueden hacer llegar sus dudas y las estaré respondiendo, les dejo además el repositorio, en donde pueden revisar el código y la documentación oficial de Rails sobre i18n.

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.

Lección anterior Primeros pasos con Ruby on Rails