Rails link alla pagina corrente e passaggio di parametri ad esso
-
23-09-2019 - |
Domanda
sto aggiungendo I18N alla mia applicazione Rails passando la versione locale con params url. Le mie gli URL sono alla ricerca come http://example.com/en/users e http://example.com/ar/users (per le impostazioni internazionali inglese e arabo, rispettivamente)
Nel mio file percorsi, ho definito miei percorsi con un: un'opzione path_prefix:
map.resources :users, :path_prefix => '/:locale'
E locale è stato impostato con un before_filter definito ApplicationController
def set_locale
I18n.locale = params[:locale]
end
I definito anche ApplicationController # default_url_options, per aggiungere locale a tutti gli URL generati dall'applicazione:
def default_url_options(options={})
{:locale => I18n.locale}
end
Quello che voglio è quello di aggiungere un link nell'intestazione di layout (visualizzato in tutte le pagine) che collegherebbe alla stessa pagina, ma con l'altro locale.
Per esempio, se sto dando un'occhiata al locale araba, voglio un link "inglese" nell'intestazione, che mi reindirizzare indietro alla mia pagina corrente, e impostare le impostazioni internazionali per inglese. C'è un modo per fare questo in rotaie?
Soluzione
ho messo un po 'a trovare questo, ma qui è la mia soluzione:
link_to 'English', url_for( :locale => 'en' )
link_to 'Deutch', url_for( :locale => 'de' )
Dalla documentazione qui: http://api.rubyonrails.org/classes /ActionController/Base.html#M000649
Quando si genera un nuovo URL, mancante valori possono essere compilati dal i parametri di richiesta corrente. Per esempio, url_for: action => ‘Some_action’ manterrà la corrente controllore, come previsto. Questo comportamento si estende ad altri parametri, tra cui : Controllore,: id, e qualsiasi altra parametri che vengono inseriti in un percorso di percorso.
Quindi, utilizzando url_for sarà di default ai parametri della richiesta corrente, basta cambiare il proprio volete nel codice. In questo caso tutto quello che ho cambiato è stato: locale, in modo da tutto il resto rimane lo stesso.
Si noti che questo funziona anche per "nascosti": i parametri. Quindi, se avete:
map.my_map ':locale/my_map', :controller => 'home', :action => 'my_map'
utilizzando l'url_for sopra nella pagina / it / my_map non avra 'casa' nella URL (es / it / home / my_map). Bonus.
Altri suggerimenti
Così ho trovato il modo di fare di più in modo esplicito questo con fuori basandosi su (tanto) rotaie magia.
url_for(params.merge({:your_new_parameter => value}))
Questo dovrebbe funzionare in qualsiasi link_to
.
Tutto il suo fare sta prendendo i parametri della richiesta corrente e la fusione la nuova hash desiderato in loro e quindi la creazione di un nuovo URL per questo.
Link alla pagina corrente con diversi locali
Testato on Rails 4
Ciao a tutti. Dopo qualche tempo di ricerca ho deciso di scrivere la mia soluzione per questo.
link_to 'English', url_for( :locale => 'en' )
link_to 'Deutch', url_for( :locale => 'de' )
Questo funziona perfetto, ma permette XSS Vulnerability solo di passaggio parametri nell'URL come di seguito:
http://localhost:3000/en/about?host=www.fishingsiteorbadurl.com/%23&port=80
In alternativa caso peggiore:
http://localhost:3000/en/about?host=%D0%BE%D1%87%D0%B5%D0%BD%D1%8C%D0%BF%D0%BB%D0%BE%D1%85%D0%BE%D0%B9%D1%81%D0%B0%D0%B9%D1%82.%D1%80%D1%84
Controlla che cosa URL si ottiene dopo aver attraversato questo link nella vostra applicazione.
La mia soluzione di produzione. Metodo "cambia lingua" reindirizza a una pagina qualsiasi con una corretta localizzazione semplicemente utilizzando HTTP_REFERER in oggetto di richiesta. Si prega di notare: il metodo URI.path per ottenere solo percorso, non tutta l'url
Fai metodo del "cambio della lingua" in qualsiasi controllore:
def change_lang
if request.referer.nil?
refer = root_url
else
uri = URI(request.referer)
refer = uri.path
end
lang = params[:lang]
cookies[:locale] = lang
redirect_to refer
end
application_controller.rb
before_action :set_locale
def set_locale
# -- Get lang from cookies or url parameter locale
user_locale = cookies[:locale] || params[:locale]
# -- If present
if user_locale.present?
# -- If it is has 2 symbols
user_locale = user_locale.scan(/[a-zA-Z]{2}/)
else
# -- If no - use default en locale
user_locale = 'en'
end
# -- Check, is this locale available for using.
# Please note: this needed for disable invalid locale warning.
if I18n.available_locales.include?(user_locale[0].to_sym)
I18n.locale = user_locale[0]
else
I18n.locale = "en"
end
end
aggiungere questo al layout
<%= link_to 'English', change_lang_path('en') %> <%= link_to 'Russian', change_lang_path('ru') %>
config / routes.rb
scope "(:locale)", locale: /[a-zA-Z]{2}/ do
get "change_lang/:lang" => "users#change_lang", :as => "change_lang"
end
Non v'è alcuna necessità di utilizzare params.merge o qualsiasi soluzione scimmia-patch.
Spero che questo aiuta, perché io personalmente speso un sacco di tempo per risolverlo.
È possibile analizzare REQUEST_URI, e sostituire il locale nel percorso con l'espressione regolare
Ok, qui è esempio aiutante. Se ho capito bene l'obiettivo
def locale_url(url, locale)
url.gsub(/\/\w*$/, "/#{locale}")
end
url = "http://www.domain.com/products/1/ru" # or request.request_uri
locale = "en"
locale_url(url, locale) #=> "http://www.domain.com/products/1/en"
Questo è un punto di partenza, in modo da poter fare alcune cose diverse che è necessario
Date un'occhiata a questo, anche se non può essere uno DRY e propria, ma funziona perfettamente per me. Si legge tutti i parametri forniti di sostituire solo il locale EX gli url: http://example.com:3000/us/users?t= 123 & m = 343 etc
def us_link
link_to "US", form_locale_url("/us")
end
def jp_link
link_to "Japan",form_locale_url("/jp")
end
def form_locale_url(locale)
new_url = request.request_uri
new_locale_url = new_us_url = new_jp_url = new_url
if new_url == "/"
new_locale_url.sub!(/\//,locale)
elsif (new_url =~/\/us/) == 0
new_us_url.sub!(/\/us/,locale)
elsif (new_url =~/\/jp/) == 0
new_jp_url.sub!(/\/jp/,locale)
end
end
A molto più veloce viale - e conveniente se si dispone di molti parametri che cambiano in luoghi diversi ... evitare la confusione con un tag di ancoraggio che appena si fonde la nuova param locale a quelli già esistenti (e in realtà uccidendo il vecchio param locale) .
<%= link_to "ру", request.params.merge( locale: 'ru' ) %>