public

Desplegar los idiomas que estan disponibles en tu App y setear el valor para cada usuario

  • Download Gist
Selector de Idioma con Rails 2.3.8
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
#Selector de idioma
#dependencias:
# 1 - Rack locale del paquete Rack-contrib [1]
# USO: Se usa para detectar el idioma definido por el usuario en su browser ['HTTP_ACCEPT_LANGUAGE']
# Esplicado aquí http://guides.rubyonrails.org/i18n.html#using-accept-language
# [1] http://github.com/rack/rack-contrib
# 2 - Routing-filter [1]
# USO: Establecer el locale en las URLs ej.: www.mysite.com/es/foo/bar
# NOTA: Si tambien quieres traducir las URL's usa la gema de Raul Murciano Translate_routes [2] (De momento sin cobertura para Rails3)
# NOTA2: Este plugin esta orientado a Rails 3, pero la version <= 0.0.2 es compatible con Rails 2.3.x
# Descargar script/plugin install git://github.com/svenfuchs/routing-filter.git --revision 'refs/tags/v0.0.2'
# [1] http://github.com/svenfuchs/routing-filter
# [2] http://github.com/raul/translate_routes
# Una vez que tetemos las dependencias a mano, las colocamos donde toca:
 
# 1 Rack locale:
#ARCHIVO => enviroment.rb
require 'rack/contrib'
Rails::Initializer.run do |config|
# middlewares extras
config.middleware.use 'Rack::Locale'
 
# 2 Routing-filter
#ARCHIVO => routes.rb
# A partir de ahora todas las rutas generadas por los helpers de Rails llevaran el locale de serie :O
map.filter :locale
# 3 En la vista (en la que tu quieras que se vea el selector)
# En mi caso es una sencilla lista de idiomas. No muestro el actual
<ul>
<% I18n.available_locales.each do |locale| %>
<% unless locale == I18n.locale %>
<li><%= link_to I18n.t("meta.language_name", :locale => locale.to_sym), change_locale_path(:new_locale => locale) %></li>
<% end %>
<% end %>
</ul>
 
# Ok, ahora sólo queda por hacer dos cosas
# a) Setear el locale
# b) Recoger el locale
# a) Recoger el locale
# NOTA: Este metodo puede ir en cualquier controlador, pero como me recomendo Fernado Blat tiene sentido que valla en sessions_controller
# user_sessions_controller.rb
def set_user_language
if params[:new_locale]
locale = params[:new_locale]
# Creamos una cookie con el locale elegido por el usuario (para los no reistrados)
cookies[:current_locale] = {:value => locale, :expires => 1.year.from_now}
if logged_in?
# Si el usuario esta registrados almacenamos su locale en la BBDD
current_user.profile.language = locale
current_user.save
end
end
# NOTA: Aquí podríamos hacer un redirec_to :back que te devuelve a la acción anterior.
# Pero si la accion anterior es POST, PUT o DELETE. EL redirect_to fallara
# SOLUCION (Made in Fernando Blat) Comprobar si la accion es GET y si lo es almacenarla en session ¿cómo? **
redirect_to session[:last_get_url]
end
# b) Recoger el locale
# ARCHIVO => application_controller.rb
before_filter :get_user_language
# ...
private
def get_user_language
if logged_in?
# Si esta logado cogemos el locale de la BBDD
I18n.locale = current_user.profile.language.to_sym unless current_user.profile.language.blank?
elsif cookies[:current_locale]
# Si no esta logado pero existe la cookie la usamos
I18n.locale = cookies[:current_locale].to_sym
elsif I18n.available_locales.include?(request.env['rack.locale'].to_sym)
# Esta variable (request.env['rack.locale']) la tenemos gracias a Rack::locale
# Si no esta logado y no habia nunca cambiado de idioma cogemos el idioma que tenga en su navegador si lo tenemos
I18n.locale = request.env['rack.locale'].to_sym
else
# Si el idioma de su navegador no es uno de los que nuestra App dispone, le ponemos el idioma por defecto
I18n.locale = I18n.default_locale
end
end
# --------------------------------------------------------------------------------------------------------------
# ** Return to POST actions
# No se puede volver a acciones POST, por eso almacenamos en sesion la accion anterior a la que fue POST.
# Seteamos esta cookie de session para recoger la ultima URL que fue GET para devolver al usuario
# En caso de que se le ocurra pulsar el cambio de idioma cuando su ultima accion fue por POST, PUT o DELETE
 
# ARCHIVO => application_controller.rb
after_filter :last_get_url
 
def last_get_url
if request.method == :get
session[:last_get_url] = request.request_uri
end
end

Como curiosidad, la forma en la que se traducen los idiomas en la vista:
Ejemplo castellano:
#locale/es.yml
es:
meta:
language_name: "Castellano"
#view.html.erb
<%= link_to I18n.t("meta.language_name", :locale => locale.to_sym), url %>

Si os fijais locale es una variable que I18n ya conoce. Realmente no la interpola, sino que la usa para ver en que archivo locale busca la traducción.
Me parece genial!

De nada, me alegro de que te haya servido :)

Great stuff!!! Could someone please translate the main points of the comments in this gist to english :) Thanks!

Also, could someone please help port this example to Rails 3 :)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.