Rails lien vers la page en cours et le passage de paramètres à ce
-
23-09-2019 - |
Question
J'ajoute I18N à mes rails l'application en passant les paramètres régionaux en utilisant params url. Mes urls sont à la recherche comme http://example.com/en/users et http://example.com/ar/users (pour les paramètres régionaux anglais et arabe respectivement)
Dans mon fichier itinéraires, j'ai défini mes itinéraires avec: option path_prefix:
map.resources :users, :path_prefix => '/:locale'
locale est définie à l'aide d'un before_filter défini dans ApplicationController
def set_locale
I18n.locale = params[:locale]
end
I également décrit ApplicationController # default_url_options, d'ajouter locale à tous les urls générées par l'application:
def default_url_options(options={})
{:locale => I18n.locale}
end
Ce que je veux est d'ajouter un lien dans l'en-tête de la mise en page (affiché dans toutes les pages) qui relierait à la même page, mais avec l'autre locale.
Par exemple, si je suis en train de naviguer les paramètres régionaux arabe, je veux un lien « anglais » dans l'en-tête, qui me rediriger vers ma page en cours et définir les paramètres régionaux pour l'anglais. Est-il possible de le faire dans des rails?
La solution
Il m'a fallu un certain temps pour trouver cela, mais voici ma solution:
link_to 'English', url_for( :locale => 'en' )
link_to 'Deutch', url_for( :locale => 'de' )
De la documentation ici: http://api.rubyonrails.org/classes /ActionController/Base.html#M000649
Lors de la génération d'une nouvelle URL, manquant Les valeurs peuvent être remplis à partir de la Les paramètres de requête en cours. Pour exemple, url_for: action => « Some_action » conservera le courant contrôleur, comme prévu. Ce comportement étend à d'autres paramètres, y compris : Contrôleur,: id, et tout autre paramètres qui sont placés dans un chemin de la route.
Donc, en utilisant url_for par défaut le paramètres de requête en cours, il suffit de changer le son que vous voulez dans votre code. Dans ce cas, tout ce que je changé était: locale, donc tout reste bien le même.
Notez que cela fonctionne aussi pour « cachées »: paramètres. Donc, si vous avez:
map.my_map ':locale/my_map', :controller => 'home', :action => 'my_map'
en utilisant le url_for ci-dessus dans la page / en / my_map aura pas 'chez soi' dans l'URL (ie / fr / home / my_map). Bonus.
Autres conseils
Alors j'ai trouvé un moyen de plus faire explicitement avec en appuyant sur (comme beaucoup) rails magique.
url_for(params.merge({:your_new_parameter => value}))
Cela devrait fonctionner dans tous les link_to
.
Tout son fait prend les paramètres de demande actuelle et la fusion de votre nouveau hachage désirée en eux et puis en créant une nouvelle URL pour cela.
Lien vers la page en cours avec différents endroits
Testé sur Rails 4
Bonjour à tous. Après un certain temps de la recherche, je décide d'écrire ma propre solution pour cela.
link_to 'English', url_for( :locale => 'en' )
link_to 'Deutch', url_for( :locale => 'de' )
Cela fonctionne parfaitement, mais il permet XSS vulnérabilité simplement le passage de paramètres dans votre URL comme ci-dessous:
http://localhost:3000/en/about?host=www.fishingsiteorbadurl.com/%23&port=80
Ou pire des cas:
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
Voyez ce que les URL que vous obtiendrez après avoir traversé ce lien dans votre application.
Ma solution de production. Méthode « Change language » redirige vers une page avec locale appropriée juste en utilisant HTTP_REFERER dans l'objet de la demande. S'il vous plaît noter: méthode URI.path pour obtenir le chemin, et non toute url
Faire méthode "changer la langue" dans un contrôleur:
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
ajouter à votre mise en page
<%= 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
Il n'y a pas besoin d'utiliser params.merge ou toute autre solution-patch de singe.
J'espère que cette aide, parce que je personnellement passé beaucoup de temps pour le résoudre.
Vous pouvez analyser request_uri et remplacer vos paramètres régionaux dans le chemin avec l'expression régulière
Ok, voici par exemple aide. Si je comprends bien l'objectif
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"
Ceci est un point de départ, de sorte que vous pouvez faire quelques choses différentes que vous avez besoin
Jetez un oeil à cela, mais il ne peut pas être sec et propre, mais fonctionne parfaitement pour moi. Il lit tous les paramètres que vous avez fournies ne remplaçant que les paramètres régionaux EX urls: 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
beaucoup plus rapide avenue - et pratique si vous avez beaucoup de paramètres qui changent à différents endroits ... éviter l'encombrement avec une balise d'ancrage qui fusionne juste pour ceux qui existent déjà la nouvelle locale param (et tuant en fait l'ancienne locale param) .
<%= link_to "ру", request.params.merge( locale: 'ru' ) %>