Frage

Wie kann ich meine Routen wie folgt einen optionalen Präfixparameter erkennen lassen:

/*lang/controller/id

Da ist der Lang -Teil optional und hat einen Standardwert, wenn er in der URL nicht angegeben ist:

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

BEARBEITEN

Im Idealfall möchte ich dies über viele Controller und Aktionen hinweg tun, indem ich einen Namespace zuordne:

map.namespace "*lang" do |lang|
  lang.resources :posts
  lang.resources :stories
end
War es hilfreich?

Lösung

Ok, ich habe es geschafft, dieses Problem zu lösen:

Es gibt keine Möglichkeit, dies standardmäßig in Rails zu tun (zumindest noch nicht). Anstatt Namespaces und Standardwerte zu verwenden, musste ich installieren Sven Fuchs 'Routing -Filter.

Sobald das Plugin installiert ist, habe ich mein LIB -Verzeichnis die folgende Datei hinzugefügt:

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

Ich habe diese Zeile zu Routen hinzugefügt.RB:

map.filter 'locale'

Dies füllt im Grunde genommen ein vor und nach dem Haken aus, das vom Plugin erzeugt wird und das Ruting der Schienen einbringt.

Wenn eine URL erkannt wird und die Rails etwas damit anfangen kann, wird die Methode um die rund_recognize aufgerufen. Dadurch wird ein Zwei-Buchstaben-Code extrahiert, der das Gebietsschema darstellt, und übergeben ihn in den Params, wobei er nicht zu 'EN' liegt, wenn kein Gebietsschema angegeben ist.

Wenn eine URL erzeugt wird, wird der Ort des Gebietsschemas in die URL auf der linken Seite gedrückt.

Dies gibt mir die folgenden URLs und Zuordnungen:

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

Alle vorhandenen URL -Helfer arbeiten wie zuvor. Der einzige Unterschied besteht darin, dass das Gebietsschema nicht festgelegt ist, sondern erhalten bleibt:

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

Andere Tipps

Sie können Standardeinstellungen in einer Route mit dem definieren :defaults Schlüssel. Versuche dies:

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

Ich verstehe, dass diese alte Frage, aber sie kann nützlich sein.

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

Und Sie müssen vor dem Filter zum Anwendungscontroller hinzufügen, um das Gebietsschema zu definieren, wie z.

before_filter :define_locale

def define_locale
  if params[:locale] == nil
    I18n.locale = 'en'
  else
    I18n.locale = params[:locale]
  end
end

Ich vermute (momentan keine Zeit zum Testen), dass dies funktionieren könnte:

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

Ok, probiert es aus - es funktioniert zumindest auf Rails 2.1.1. Das ist gut. Ich kann die Idee jedoch nicht zum Laufen bringen, was eine Schande ist, weil es Trockner ist.

Ich dachte, Sie könnten einmal einen [Schlüssel] => nil verwenden, um einen optionalen Parameter anzugeben. Etwas wie:

map.connect ':lang/posts/:id', :controller => 'posts', :action => 'show', :lang => nil
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top