Ruby on Rails中自动设置本地语言

12
如何在Ruby on Rails上自动设置区域设置?例如,如果网页在西班牙打开,则locale = es,类似地,如果在英国,则locale = en等等?
请帮忙。

请查看此链接中的2.6.2使用GeoIP(或类似)数据库。 - piam
1
@NickGinanto 这篇文章很久以前写的。我最终使用了I18n宝石。使用这些宝石可以让应用程序根据用户浏览器的语言设置来显示他们所选择的首选语言环境。这意味着如果用户愿意,他们可以查看其他语言环境。 - RajG
5个回答

28

您可以在您的ApplicationController中像这样实现它:

class ApplicationController < ActionController::Base
  before_filter :set_locale

  def set_locale
    I18n.locale = extract_locale_from_headers
  end

  private

  def extract_locale_from_headers
    request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first.presence || 'en'
  end
end

它将“检查”收到的请求,找到客户端浏览器的语言,并将其设置为您的I18n区域设置。
请查看RubyOnRails指南,了解更多有关I18n的说明。
我强烈建议设置一组支持的语言环境,并回退到默认语言环境。可以这样做:
ALLOWED_LOCALES = %w( fr en es ).freeze
DEFAULT_LOCALE = 'en'.freeze

def extract_locale_from_headers
  browser_locale = request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first
  if ALLOWED_LOCALES.include?(browser_locale)
    browser_locale
  else
    DEFAULT_LOCALE
  end
end

这段代码对于真实用户来说是有效的,但对于机器人和搜索引擎来说非常糟糕 - 它们都会收到500错误,因为请求中没有env ['HTTP_ACCEPT_LANGUAGE'],如果您仍然想使用此代码,请检查:if!request.env ['HTTP_ACCEPT_LANGUAGE']. blank? - r3cha
这就是为什么我添加了备受推荐的回退 @RomanKlevtcov。 - MrYoshiji
哦,现在看到了,抱歉。 我们也可以更新代码: - r3cha

9

尝试使用gem geocoderi18n_data gem,并在before_filter中调用一个方法来执行以下操作:

def checklocale
  I18n.locale =  I18nData.country_code(request.location.country) 
end

安装了这两个gems,但是没成功 :( ... 如果我能让你的代码运行,那么我就可以编写更好的代码,比如,如果浏览器在进行http头请求时没有回复,则我可以使用你的想法来实现获取位置/国家数据,然后根据它来设置语言环境。但遗憾的是它没有显示任何值。但我非常愿意使用你的代码而不是使用“geoip”。也许你可以给我一个替代指针。谢谢。 - RajG
在开发模式下它可以工作(但在生产环境中无法工作),但是为什么第一个字母必须大写呢?当我输入“西班牙”时它不起作用。同样,对于“德国”或“德国人”,也不能正常工作。当我们执行 @country=I18nData.country_code(request.location.country) 时,它只提取“国家名称”吗?谢谢! - RajG
request.location.country会给你返回请求来源的国家名称。所以,如果用户从德国访问一个网站,request.location.country将返回"Germany"。在生产环境中,request.location.country会给你什么呢?可能是你的托管服务代理了你的请求,并将IP地址更改为内部IP地址。 - Nick Ginanto
6
我认为基于GeoIP的本地化是无意义的。考虑两种情况:你来自墨西哥并前往日本旅行,在日本的免费WiFi上访问你最喜欢的应用程序,结果就会 BAM:你看到了日语界面,但你什么也看不懂。第二种情况:你的一位德国客户连接到她最喜欢的星巴克咖啡店的WiFi,但WiFi提供商(BT WiFi)位于英国,因此用户的IP地址也是英国的,结果 BAM:她得到了英文版的应用程序。我建议使用HTTP_ACCEPT_LANGUAGE头文件的解决方案,这样你可以为你的用户提供他们首选的语言。 - Martin Röbert
@MartinRöbert 我搞定了 :p BAM - RajG
显示剩余12条评论

4

将此包含在ApplicationControllerBaseController中。

before_filter :set_locale

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

这意味着将locale设置为默认值或使用请求中的语言环境,优先使用请求中发送的语言环境。如果您想将其扩展到用户、会话、请求,则可以这样做。
def set_locale
  I18n.locale = @user.locale || session[:locale] || params[:locale] || I18n.default_locale
end

More info here Similar question.


1

如果我理解正确的话,您将需要使用地理定位功能,根据用户的IP地址获取其位置,然后根据此设置区域设置,但是在无法获取用户的IP地址时,您必须不要忘记设置一些默认值。

很抱歉,但我还没有在Ruby上使用过地理定位功能。我在Rubygems上进行了快速搜索,但未能找到任何可简化您工作的gem。=(


查看我的答案以获取适当的宝石。 - Nick Ginanto

0

Rails指南中,将此代码包含在ApplicationController中

before_action :set_locale

def set_locale
  I18n.locale = extract_locale_from_tld || I18n.default_locale
end

# Get locale from top-level domain or return nil if such locale is not available
# You have to put something like:
#   127.0.0.1 application.com
#   127.0.0.1 application.it
#   127.0.0.1 application.pl
# in your /etc/hosts file to try this out locally
def extract_locale_from_tld
  parsed_locale = request.host.split('.').last
  I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil
end

本质上,这会从类似于application.co.id或example.com的URL中剥离最后一个标识符(.en、.id等),并根据此设置区域设置。如果用户来自您不支持的语言环境,则返回默认语言环境 - 英语,除非另有设置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接