0

次のコードは、最初にparamに基づいて、次に以前に設定された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

4

1 に答える 1

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

はsto_snil処理し、ラムダと追加の変数はロジックを明確にするためにあります。これを行う必要はありません。本当に必要なのは、ユーザーとユーザーの好みで並べ替えられたソフトウェアの両方に受け入れられる言語コードを返すメソッドだけです。

に戻りset_localeます。'en'URLまたはCookieの内容に関係なく、Accept-Langauge(フォールバックとして)と一致する言語が必要であると言います。つまり、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

于 2012-08-30T19:22:13.477 に答える