我有以下代码,用于首先根据参数分配区域设置,然后分配先前设置的Cookie,然后请求HTTP_ACCEPT_LANGUAGE
。
def set_locale
if params[:locale]
I18n.locale = params[:locale]
elsif cookies[:locale]
I18n.locale = cookies[:locale]
else
I18n.locale = sanitizeLocale(request.env["HTTP_ACCEPT_LANGUAGE"]) # e.g. "en,es;q=0.8,de-de;q=0.5,en-us;q=0.3"
end
cookies[:locale] = I18n.locale
end
def sanitizeLocale(locale)
@locale, lang_weight = cookies[:locale] || begin
if accept_lang = request.env["HTTP_ACCEPT_LANGUAGE"] # e.g. "en,es;q=0.8,de-de;q=0.5,en-us;q=0.3"
accept_lang.to_s.split(',').collect {|l| x,y = l.split(';q='); [x.split('-').first, (y||1).to_f]}.sort_by(&:last).reverse.find {|lang, lang_weight| %w[es en it fr de].include?(lang)}
# returns ["en", 1.0]
end
end || 'en' # default
return @locale
end
我的问题是如何检查params[:locale]
给定和cookies[:locale]
对sanitizeLocale
。我很有兴趣只根据输入获得有效值,例如es en it fr de
或默认为en。
我一直试图将其值传递给sanitizeLocale
同样我正在为HTTP_ACCEPT_LANGUAGE
执行某些我无法理解的工作,并且始终默认为en
当params[:locale]
给定值有效时,如it
。
答案 0 :(得分:0)
首先,我们可以简化您的Accept-Language解析:
def acceptable_langs
extract_langs = lambda do |l|
x, y = l.split(';q=')
[x.split('-').first, -(y || 1).to_f] # the -1 makes sort_by nicer
end
known_langs = lambda { |lang| %w[es en it fr de].include?(lang.first) }
quality = :last
language = :first
langs = request.env['HTTP_ACCEPT_LANGUAGE'].to_s
.split(',')
.map(&extract_langs)
.select(&known_langs)
.sort_by(&quality)
.collect(&:language)
langs + ['en']
end
to_s
将处理nil
,lambdas和额外变量就是为了澄清逻辑。您不必这样做,您真正需要的是一种方法,该方法返回用户和您的软件所订购的软件可接受的语言代码。
现在回到set_locale
。您说您需要使用与Accept-Langauge匹配的语言(使用'en'
作为后备),无论URL或Cookie必须说什么。这意味着无论如何都必须解析Accept-Language,然后针对该列表检查params[:locale]
和cookies[:locale]
:
def set_locale
# Figure out what they're asking for with English as the
# default. Note that `acceptable_langs` always forces English
# to be in the list.
asking_for = params[:locale] || cookies[:locale] || 'en'
# acceptable_langs is always in preference order so we just
# want the first one that matches our `lang`.
lang = acceptable_langs.find { |lang| asking_for == lang }
# Now we have an acceptable language in `lang` (thanks to all
# the `'en'` fallbacks we sprinkled about).
I18n.locale = cookies[:locale] = lang
end
您还可以在Cookie中添加一些“我已经完成所有这些工作”标志,这样如果设置了标志,您就可以信任cookies[:locale]
;尽管如此,可能没有理由过早地优化set_locale
。