I18n.locale重置为:en在控制器和视图之间

时间:2014-10-12 05:23:58

标签: ruby-on-rails internationalization locale spree rails-i18n

我正在尝试使用spree自己的spree_i18n gem来国际化Rails / Spree应用程序,但我无法让它工作。

I made a minimal app which recreates the problem here.

简而言之,我在ApplicationController中有以下代码:

before_action :set_locale

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

我视图中的代码应该被翻译(<%= t("whatever") %>)。但无论我做什么,文本总是以英文输出。

使用一些额外的调试代码,我可以看到一旦set_locale被调用但执行仍然在控制器内,那么语言环境是正确的(例如,如果我访问URL /?locale=es,那么上述控制器代码中的puts语句输出es)。

但是当执行到达视图时,语言环境已经以某种方式重置为en。 (例如,在视图中添加<% raise I18n.locale.to_s %>会引发&#34; en&#34;作为错误消息。)

opened an issue on Spree's Github因为据我所知,我已完全按照他们的指示操作,但仍然没有工作,但我可能仍然遗漏了一些东西。为什么区域设置没有正确设置?

(注意:我应该补充说Spree.t也不起作用,而不只是t。)

编辑:如果你查看我的Github问题的评论,你会发现我的工作正常。但是,我99%肯定我的解决方案是黑客,而且我应该使用更好的方法。赏金告诉任何能告诉我自己错误的人。

3 个答案:

答案 0 :(得分:5)

Spree I18n提供了一种设置默认语言的方法:在config/application.rbconfig.i18n.default_locale = :es

设置语言的可能性有所改变。也许在config/initializers/spree_i18n.rb

SpreeI18n::Config.available_locales = [:en, :es, :de] 
SpreeI18n::Config.supported_locales = [:en, :es, :de] 

之后,您可以删除ApplicationController上的set_locale,因为它没有效果。

有了这个,它就像一个魅力。

编辑:

我更改了错误消息,因为我想确保它有效:

<%= product_description(@product) rescue Spree.t(:product_has_no_description) +
' ' + Spree.t(:action) %>

我添加了一个没有描述的新产品。在localhost上运行服务器

在英语中我看到:“此产品没有描述行动”

西班牙语中我看到:“Este producto no tiene描述Acción”

在德意志中,我看到:“产品帽子kech Beschreibung Aktion”

完全符合预期。

您可以在github

看到包含更改的来源

答案 1 :(得分:2)

我不清楚Spree如何处理本地化,而routes.rb只能挂载引擎。

基本上,您应该通过添加:

开始在routes.rb内本地化您的应用
scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
  # routing and engines go here
end

现在,您需要在请求之间保留params[:locale],因此请添加到app控制器:

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

最后,检测并设置当前请求的区域设置,具体取决于您的输入数据:

before_filter :set_locale

def set_locale
  if defined?(params) && params[:locale]
    I18n.locale = params[:locale]
  elsif current_user && current_user.language_id.present?
    I18n.locale = current_user.language.code
  elsif defined?(request)
    I18n.locale = extract_locale_from_accept_language_header
  end
  I18n.locale ||= I18n.default_locale
  I18n.locale = :en unless valid_languages.include?(I18n.locale.to_sym)
end

答案 2 :(得分:1)

using/setting中的app/controllers/application_controller.rb以下内容可能不起作用:

before_action :set_locale
def set_locale
    I18n.locale =
    Spree::Frontend::Config[:locale] =
    Spree::Backend::Config[:locale] = :LOCALE
end

core/lib/spree/core/controller_helpers/common.rb中,还有另一个名为before_filter的{​​{1}}。调用该过滤器并将语言环境重新设置为set_user_language的值,或者如果未定义,则使用默认语言环境。

要解决此问题,请在before_filter中设置session[:locale] =:LOCALE。