Question Rails lient à la page en cours et lui transmet des paramètres


J'ajoute I18N à mon application rails en passant les paramètres régionaux en utilisant les paramètres url. Mes urls ressemblent http://example.com/en/users et http://example.com/ar/users (pour les environnements anglais et arabe respectivement).

Dans mon fichier de routes, j'ai défini mes itinéraires avec une option: path_prefix:

map.resources :users, :path_prefix => '/:locale'

Et les paramètres régionaux sont définis en utilisant un before_filter défini dans ApplicationController

def set_locale
    I18n.locale = params[:locale]
end

J'ai également défini ApplicationController # default_url_options, pour ajouter des paramètres régionaux à toutes les URL générées par l'application:

def default_url_options(options={})
    {:locale => I18n.locale}
end

Ce que je veux, c'est ajouter un lien dans l'en-tête de présentation (affiché dans toutes les pages) qui serait lié à la même page, mais avec les autres paramètres régionaux.

Par exemple, si je navigue dans la langue arabe, je veux un lien «anglais» dans l’en-tête, qui me redirigera vers ma page actuelle et définira les paramètres régionaux en anglais. Y a-t-il un moyen de le faire dans les rails?


46
2018-03-30 07:50


origine


Réponses:


Il m'a fallu du temps pour trouver ceci mais voici ma solution:

link_to 'English', url_for( :locale => 'en' )
link_to 'Deutch', url_for( :locale => 'de' ) 

Des documents 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 remplies à partir du   paramètres actuels de la demande. Pour   exemple, url_for: action =>   'Some_action' conservera le courant   contrôleur, comme prévu. Ce comportement   étend à d'autres paramètres, y compris   : controller,: id, et tout autre   les paramètres qui sont placés dans un   Chemin de la route.

Donc, utiliser url_for par défaut pour les paramètres de la requête actuelle, changez simplement celui que vous voulez dans votre code. Dans ce cas, tout ce que j'ai changé était: locale, donc tout le reste reste le même.

Notez que cela fonctionne également pour les paramètres "cachés": Donc, si vous avez:

map.my_map ':locale/my_map', :controller => 'home', :action => 'my_map'

utiliser l'url_for ci-dessus dans la page / fr / my_map n'aura pas "home" dans l'URL (par exemple / en / home / my_map). Prime.


108
2018-04-28 21:04



J'ai donc trouvé un moyen de le faire plus explicitement sans compter sur (autant) la magie des rails.

url_for(params.merge({:your_new_parameter => value}))

Cela devrait fonctionner dans n'importe quel link_to.

Tout ce qu'il fait est de prendre les paramètres de la requête actuelle et de fusionner leur nouveau hachage souhaité, puis de créer une nouvelle URL pour cela.


14
2017-09-06 04:26



Lien vers la page en cours avec différents paramètres régionaux

Testé sur Rails 4

Bonjour à tous. Après un certain temps de 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 cela permet Vulnérabilité XSS il suffit de passer des paramètres dans votre URL comme ci-dessous:

http://localhost:3000/en/about?host=www.fishingsiteorbadurl.com/%23&port=80

Ou pire 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

Vérifiez les URL que vous obtiendrez après avoir parcouru ce lien dans votre application.

Ma solution de production La méthode "change le langage" redirige vers n'importe quelle page avec les paramètres régionaux appropriés en utilisant simplement HTTP_REFERER dans l'objet request. Veuillez noter: la méthode URI.path pour obtenir un chemin uniquement, pas une URL complète

Faire la méthode "change de langue" dans n'importe quel 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

ajoutez ceci à 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'est pas nécessaire d'utiliser params.merge ou une solution de patch de singe.

J'espère que cela aide, car j'ai personnellement passé beaucoup de temps à le résoudre.


5
2018-02-03 11:16



Vous pouvez analyser request_uri et remplacer vos paramètres régionaux par des expressions régulières.

Ok, voici un exemple d'aide. Si je comprends bien le but

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, donc vous pouvez faire des choses différentes dont vous avez besoin


2
2018-03-30 08:00



Jetez-y un coup d'œil, même si ce n'est peut-être pas sec et correct, mais fonctionne parfaitement pour moi. Il lit tous les paramètres que vous avez fournis en 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

1
2018-03-28 05:30