Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

ruby on rails - How to change the locale through URL?

In my bi-lingual Rails 4 application I have a LocalesController like this:

class LocalesController < ApplicationController

  def change_locale
    if params[:set_locale]
      session[:locale] = params[:set_locale] 
      url_hash = Rails.application.routes.recognize_path URI(request.referer).path
      url_hash[:locale] = params[:set_locale]
      redirect_to url_hash
    end
  end

end

A User can change his locale through this form:

def locale_switcher
  form_tag url_for(:controller => 'locales', :action => 'change_locale'), :method => 'get', :id => 'locale_switcher' do
  select_tag 'set_locale', options_for_select(LANGUAGES, I18n.locale.to_s)
end

This works.

However, right now there's no way for the user to change the language via the URL.

E.g. if a user is on the page www.app.com/en/projects and then manually changes the URL to www.app.com/fr/projects, he should see the French version of the page, but instead nothing happens.

This may not matter in many Rails apps but in mine it is quite important.

How can it be fixed?

Thanks for any help.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is how I did it in one of Rails 4 applications:

in config/routes.rb:

Rails.application.routes.draw do
  scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
    # rest of your routes here
    # for example:
    resources :projects
  end
end

make sure in config/environments/production.rb this line is uncommented:

config.i18n.fallbacks = true

If you wish to have a default_locale setup other than :en, then in config/application.rb, uncomment this line:

config.i18n.default_locale = :de # and then :de will be used as default locale

Now, last part of your setup, add this method in ApplicationController:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  before_action :set_locale

  private
    def set_locale
      I18n.locale = params[:locale] || session[:locale] || I18n.default_locale
      session[:locale] = I18n.locale
    end

   def default_url_options(options={})
     logger.debug "default_url_options is passed options: #{options.inspect}
"
     { locale: I18n.locale }
   end
end

Now, your application can be accessed as: http://localhost:3000/en/projects, http://localhost:3000/fr/projects, or http://localhost:3000/projects. The last one http://localhost:3000/projects will use :en as its default locale(unless you make that change in application.rb).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...