8

クライアントのbrowserlocaleとURLでロケールを設定したいrequest.env['HTTP_ACCEPT_LANGUAGE']

  1. ユーザーがURL(例:myapp.com)にアクセスした場合は、をチェックHTTP_ACCEPT_LANGUAGEして正しいURLにリダイレクトする必要があります(例:myapp.com/en-enの場合browserlocale

  2. ユーザーが言語メニューから別の言語を選択した場合は、URLをmyapp.com/deなどに変更する必要があります。

これが私がこれまでに得たものです:

class ApplicationController < ActionController::Base
  protect_from_forgery
  before_filter :set_locale

private

  # set the language
  def set_locale
    if params[:locale].blank?
      I18n.locale = extract_locale_from_accept_language_header
    else
      I18n.locale = params[:locale]
    end
  end

  # pass in language as a default url parameter
  def default_url_options(options = {})
    {locale: I18n.locale}
  end

  # extract the language from the clients browser
  def extract_locale_from_accept_language_header
    browser_locale = request.env['HTTP_ACCEPT_LANGUAGE'].try(:scan, /^[a-z]{2}/).try(:first).try(:to_sym) 
    if I18n.available_locales.include? browser_locale
      browser_locale
    else
      I18n.default_locale
    end
  end
end

私のルートファイルで私は得ました:

Myapp::Application.routes.draw do
  # set language path
  scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do

    root :to => "mycontrollers#new"
    ...

  end

  match '*path', to: redirect("/#{I18n.locale}/%{path}"), constraints: lambda { |req| !req.path.starts_with? "/#{I18n.default_locale}/" }

  match '', to: redirect("/#{I18n.locale}")
end

問題は、routesfileが最初に実行され、HTTP_ACCEPT_LANGUAGE効果がないことです。これは、コントローラーに関してはurl-paramがすでに設定されているためです。

誰かがその解決策を持っていますか?たぶんミドルウェアで解決しますか?

4

1 に答える 1

8

ルートのいくつかを変更します。

初め:

scope :path => ":locale" do
  ... 
end

2番:

ここであなたがやろうとしていることがわかります。

match '', to: redirect("/#{I18n.locale}")

しかし、それは冗長に思えます。

その行を削除して、次のようにset_localeメソッドを変更するだけです。

# set the language
def set_locale
  if params[:locale].blank?
    redirect_to "/#{extract_locale_from_accept_language_header}"
  else
    I18n.locale = params[:locale]
  end
end
于 2012-05-24T19:37:53.233 に答える