Question

Comment puis-je faire en sorte que mes itinéraires reconnaissent un paramètre de préfixe facultatif comme suit:

/*lang/controller/id

En ce que la partie lang est facultative et a une valeur par défaut si elle n'est pas spécifiée dans l'URL:

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

EDIT

Idéalement, je souhaite effectuer cette opération sur plusieurs contrôleurs et actions en mappant un espace de noms:

map.namespace "*lang" do |lang|
  lang.resources :posts
  lang.resources :stories
end
Était-ce utile?

La solution

OK, j'ai réussi à résoudre ce problème:

Il n’ya aucun moyen de faire cela dans Rails par défaut (du moins, pas encore). Au lieu d'utiliser des espaces de noms et des valeurs par défaut, je devais installer le filtre de routage de Sven Fuchs . .

Une fois le plugin installé, j'ai ajouté le fichier suivant à mon répertoire 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

J'ai ajouté cette ligne à routes.rb:

map.filter 'locale'

Ceci complète essentiellement un hook avant et après, généré par le plugin, qui encapsule le routage des rails.

Quand une URL est reconnue, et avant que Rails ne puisse faire quoi que ce soit avec elle, la méthode around_recognize est appelée. Ceci extraira un code de deux lettres représentant les paramètres régionaux et le transmettra dans les paramètres, par défaut à 'en' si aucun paramètre régional n'est spécifié.

De même, lorsqu'une URL est générée, le paramètre de paramètres régionaux sera inséré dans l'URL à gauche.

Cela me donne les URL et les mappages suivants:

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

Tous les helpers d'URL existants fonctionnent comme avant, la seule différence étant que, à moins que les paramètres régionaux ne soient spécifiés, ils sont préservés:

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

Autres conseils

Vous pouvez définir des valeurs par défaut dans une route à l’aide de la touche : defaults . Essayez ceci:

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

Je comprends que cette vieille question, mais elle peut être utile.

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

Et vous devez ajouter un filtre avant le contrôleur d'application pour définir les paramètres régionaux, tels que

before_filter :define_locale

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

Je devine (pas le temps de tester pour le moment) que cela pourrait fonctionner:

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

OK, essayé - cela fonctionne, du moins sur Rails 2.1.1. Donc c'est bien. Je ne parviens pas à faire fonctionner l’idée: par défaut, ce qui est dommage, car c’est DRYer.

Je pensais que vous pourriez utiliser à la fois une [clé] = > nil pour spécifier un paramètre facultatif. Quelque chose comme:

map.connect ':lang/posts/:id', :controller => 'posts', :action => 'show', :lang => nil
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top