Erstellen von Routen mit einem optionalen Pfadpräfix
-
03-07-2019 - |
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
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