Rails语言环境不是持久的

时间:2014-08-15 15:40:56

标签: ruby-on-rails ruby-on-rails-4 locale rails-i18n

我正在尝试开发双语应用。

但是,我发现默认的i18n gem不会持久保存语言环境。

我有这个索引页面,并提供了一个更改默认语言的链接。

<% if I18n.locale == I18n.default_locale %>
 <%= link_to "English", :locale=>'en'%>
<% else %>
 <%= link_to "Français", :locale=>'fr'%>
<%end%>

问题是,当我登录到另一个页面时,语言环境会回退到默认语言。

所以,我只是想知道如何保持用户语言选择并持续使用该语言环境,直到用户退出。

提前致谢。

3 个答案:

答案 0 :(得分:4)

我建议您阅读此Rails guides about I18n以了解I18n在Rails中的工作原理。很明显,I18n.locale的更改是暂时的,并且会在每个会话中重置。

根据您的要求,您可以将选定的区域设置存储在session中。以下是示例代码:

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :set_locale

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

然后,您可以在用户退出时清除session[:locale]

# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
  def sign_out
    # ...
    session.delete :locale
  end
end

答案 1 :(得分:4)

如果你看docs就说

  

您可能想要将所选的区域设置存储在会话或cookie中,但不要这样做。区域设置应该是透明的并且是URL的一部分。通过这种方式,您不会违反人们对网络本身的基本假设:如果您向朋友发送网址,他们应该会看到与您相同的网页和内容。

如果您将本地人设置为域名或网址,那么它有几个优点

1. The locale is an obvious part of the URL.
2. People intuitively grasp in which language the content will be displayed.
3. It is very trivial to implement in Rails. 
4. Search engines seem to like that content in different languages lives at different, inter-linked domains.

<强>修正

一个。 You can pass locals in urls and then set it a filter:

在这种情况下,您的网址将显示为www.example.com/books?locale=ja or www.example.com/ja/books,然后在应用程序控制器中,您可以在过滤器中设置您的网址

before_action :set_locale

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

在每个网址中包含一个显式选项(例如link_to(books_url(locale:I18n.locale)))会很乏味且可能不可能所以你可以覆盖rails default_url_options 通过应用程序控制器中的类似内容

# app/controllers/application_controller.rb
def default_url_options(options={})
  logger.debug "default_url_options is passed options: #{options.inspect}\n"
  { locale: I18n.locale }
end
  

这将允许每个依赖于url_for的辅助方法(例如,root_path或root_url等命名路由的帮助程序,books_path或books_url之类的资源路由等)现在将自动在查询字符串中包含区域设置,如下所示:{{3 }}

但是如果您希望使用您的网址看起来像www.example.com/en/books,那么您需要覆盖default_url_options方法,并且您必须按照以下方式确定路线的范围:

# config/routes.rb
scope "(:locale)", locale: /en|nl/ do
  resources :books
end

http://www.example.com/?locale=ja

人们可以在浏览器或其他客户端(例如curl)中设置Accept-Language,您可以在应用程序控制器中使用它:

def set_locale
  logger.debug "* Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}"
  I18n.locale = extract_locale_from_accept_language_header
  logger.debug "* Locale set to '#{I18n.locale}'"
end

private
  def extract_locale_from_accept_language_header
    request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first
  end

答案 2 :(得分:2)

好的做法是设置区域设置并将该区域设置添加到default_url_options中的ApplicationController a:

before_filter :set_locale

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

def default_url_options(options={})
  { locale: I18n.locale }
end

然后将范围添加到 route.rb

scope "/:locale", locale: /en|fr/ do
  your routes goes here
end

layouts / application.html.erb 中:

    <%= link_to "English", { locale: :en }%>

    <%= link_to "French", { locale: :fr } %>

度过愉快的一天。