Domanda

Come posso fare per far riconoscere ai miei percorsi un parametro di prefisso opzionale come segue:

/*lang/controller/id

In quanto la parte lang è facoltativa e ha un valore predefinito se non è specificata nell'URL:

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

Modifica

Idealmente, sto cercando di farlo attraverso molti controller e azioni mappando uno spazio dei nomi:

map.namespace "*lang" do |lang|
  lang.resources :posts
  lang.resources :stories
end
È stato utile?

Soluzione

OK, sono riuscito a risolvere questo problema:

Non c'è modo di farlo in Rails per impostazione predefinita (almeno, non ancora). Invece di utilizzare spazi dei nomi e valori predefiniti, dovevo installare Filtro di routing di Sven Fuchs .

Una volta installato il plugin, ho aggiunto il seguente file alla mia directory 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

Ho aggiunto questa linea a route.rb:

map.filter 'locale'

Questo sostanzialmente riempie un hook prima e dopo, generato dal plugin, che avvolge il routing delle rotaie.

Quando viene riconosciuto un url e prima che Rails possa farci qualcosa, viene chiamato il metodo around_recognize. Questo estrarrà un codice di due lettere che rappresenta la locale e lo passerà nei parametri, per impostazione predefinita a 'en' se non viene specificata alcuna locale.

Allo stesso modo, quando viene generato un URL, il parametro locale verrà inserito nell'URL sul lato sinistro.

Questo mi dà i seguenti URL e mappature:

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

Tutti gli helper URL esistenti funzionano come prima, con la sola differenza che, a meno che non venga specificata la locale, viene mantenuta:

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

Altri suggerimenti

Puoi definire i valori predefiniti in una rotta usando il tasto : defaults . Prova questo:

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

Capisco che questa vecchia domanda, ma può essere utile.

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

E devi aggiungere prima del filtro al controller dell'applicazione per definire le impostazioni internazionali, come

before_filter :define_locale

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

Sto indovinando (non c'è tempo per testare adesso) che questo potrebbe funzionare:

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

OK, provato - funziona, almeno su Rails 2.1.1. Quindi va bene. Non riesco a far funzionare l'idea di default, il che è un peccato, perché è ASCIUGATRICE.

Pensavo di poter usare una volta [key] = > zero per specificare un parametro facoltativo. Qualcosa del tipo:

map.connect ':lang/posts/:id', :controller => 'posts', :action => 'show', :lang => nil
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top