检查参数,根据方法定义的cookie不起作用

时间:2012-08-29 07:38:18

标签: ruby-on-rails ruby

我有以下代码,用于首先根据参数分配区域设置,然后分配先前设置的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执行某些我无法理解的工作,并且始终默认为enparams[:locale]给定值有效时,如it

1 个答案:

答案 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