#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