22

次のように、ルートにオプションのプレフィックスパラメーターを認識させるにはどうすればよいですか。

/*lang/controller/id

lang 部分はオプションであり、URL で指定されていない場合はデフォルト値があります。

/en/posts/1   => lang = en
/fr/posts/1   => lang = fr
/posts/1      => lang = en

編集

理想的には、名前空間をマッピングすることにより、多くのコントローラーとアクションにわたってこれを行うことを検討しています。

map.namespace "*lang" do |lang|
  lang.resources :posts
  lang.resources :stories
end
4

5 に答える 5

19

OK、私はこの問題を解決することができました:

デフォルトでは、Rails でこれを行う方法はありません (少なくとも、まだ)。名前空間とデフォルト値を使用する代わりに、Sven Fuchs のルーティング フィルターをインストールする必要がありました。

プラグインをインストールしたら、次のファイルを lib ディレクトリに追加しました。

require 'routing_filter/base'

module RoutingFilter
  class Locale < Base

    # remove the locale from the beginning of the path, pass the path
    # to the given block and set it to the resulting params hash
    def around_recognize(path, env, &block)
      locale = nil
      path.sub! %r(^/([a-zA-Z]{2})(?=/|$)) do locale = $1; '' end
      returning yield do |params|
        params[:locale] = locale || 'en'
      end
    end

    def around_generate(*args, &block)
      locale = args.extract_options!.delete(:locale) || 'en'
      returning yield do |result|
        if locale != 'en'
          result.sub!(%r(^(http.?://[^/]*)?(.*))){ "#{$1}/#{locale}#{$2}" }
        end 
      end
    end

  end
end

この行をroutes.rbに追加しました:

map.filter 'locale'

これは基本的に、レール ルーティングをラップする、プラグインによって生成された before および after フックを埋めます。

URL が認識されると、Rails がそれを処理する前に、 around_recognize メソッドが呼び出されます。これにより、ロケールを表す 2 文字のコードが抽出され、params で渡されます。ロケールが指定されていない場合は、デフォルトで「en」になります。

同様に、URL が生成されると、locale パラメーターが左側の URL にプッシュされます。

これにより、次の URL とマッピングが得られます。

/   => :locale => 'en'
/en => :locale => 'en'
/fr => :locale => 'fr'

既存のすべての URL ヘルパーは以前と同じように機能しますが、唯一の違いは、ロケールが指定されていない限り保持されることです。

home_path                  => /
home_path(:locale => 'en') => /
home_path(:locale => 'fr') => /fr
于 2008-10-21T08:13:04.643 に答える
2

この古い質問は理解していますが、役に立つかもしれません。

  map.with_options(:path_prefix => ":locale") do |m|
    m.resources :posts
    m.resources :stories        
  end

また、次のようなロケールを定義するために、フィルタの前にアプリケーション コントローラを追加する必要があります。

before_filter :define_locale

def define_locale
  if params[:locale] == nil
    I18n.locale = 'en'
  else
    I18n.locale = params[:locale]
  end
end
于 2010-01-30T09:23:17.237 に答える
2

キーを使用してルートのデフォルトを定義できます:defaults。これを試して:

map.connect ':lang/posts/:id', :controller => 'posts', :action => 'show',
                               :defaults => { :lang => 'en' }
于 2008-10-17T17:42:13.360 に答える
1

私はこれがうまくいくかもしれないと推測しています(今すぐテストする時間はありません):

map.connect ':language/posts/:id', :controller => 'posts', :action => 'show'
map.connect 'posts/:id', :controller => 'posts', :action => 'show'

OK、試してみました-少なくともRails2.1.1では機能します。いいですね。ただし、:defaultsのアイデアを機能させることはできません。これは、DRYerであるため、残念です。

于 2008-10-17T16:37:55.860 に答える
1

一度に [key] => nil を使用してオプションのパラメーターを指定できると考えました。何かのようなもの:

map.connect ':lang/posts/:id', :controller => 'posts', :action => 'show', :lang => nil
于 2008-10-17T21:09:19.337 に答える