質問

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

/*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
役に立ちましたか?

解決

OK、この問題を解決できました:

TRailsでデフォルトでこれを行う方法はありません(少なくとも、まだ)。名前空間とデフォルト値を使用する代わりに、 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'

これは基本的に、プラグインによって生成され、レールのルーティングをラップする前後のフックに記入します。

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

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

これにより、次のURLとマッピングが提供されます。

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

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

home_path                  => /
home_path(:locale => 'en') => /
home_path(:locale => 'fr') => /fr

他のヒント

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

map.connect ':lang/posts/:id', :controller => 'posts', :action => 'show',
                               :defaults => { :lang => 'en' }

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

  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

これが機能する可能性があると推測しています(今はテストする時間はありません):

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

OK、試してみました-少なくともRails 2.1.1では動作します。いいですねただし、:defaultsのアイデアを機能させることはできません。これは残念です。DRYerだからです。

一度に[key] =&gt;を使用できると思いました。オプションのパラメーターを指定するにはnil。次のようなもの:

map.connect ':lang/posts/:id', :controller => 'posts', :action => 'show', :lang => nil
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top