Rails lien vers la page actuelle et lui transmettre des paramètres

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

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

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

Et les paramètres régionaux sont définis à l'aide d'un filtre 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 mise en page (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 les paramètres régionaux Arabes, 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. Est-il un moyen de le faire dans les rails?

46
demandé sur Faisal 2010-03-30 11:50:59

5 réponses

M'a pris un moment 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, les valeurs peuvent être renseignées à partir paramètres de la requête actuelle. Pour exemple, url_for :action => 'some_action' conservera le courant contrôleur, comme prévu. Ce comportement s'étend à d'autres paramètres, y compris : contrôleur,: id, et tout autre paramètres qui sont placés dans un Route du chemin.

Donc, en utilisant url_for par défaut aux paramètres de la requête en cours, il suffit de changer ceux 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 aussi pour" hidden": parameters. Donc, si vous avez:

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

L'utilisation de l'url_for ci-dessus dans la page /fr/my_map n'aura pas 'home' dans l'url (ie /FR/home/my_map). Bonus.

109
répondu pixelearth 2010-04-28 21:04:05

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 votre nouveau hachage désiré en eux, puis de créer une nouvelle url pour cela.

14
répondu Will 2012-09-06 15:06:03

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

Testé sur des 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 il permet vulnérabilité XSS {[9] } juste passer des paramètres dans votre URL comme ci-dessous:

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

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

Découvrez quelles URL vous obtiendrez après avoir traversé ce lien dans votre application.

Ma production solution. La méthode "change language" redirige vers n'importe quelle page avec des paramètres régionaux appropriés en utilisant simplement HTTP_REFERER dans l'objet de requête. Veuillez noter: URI.méthode path Pour get only path, pas l'url entière

Faire" changer la langue " méthode 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'y a pas besoin d'utiliser params.fusion ou toute solution singe-patch.

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

5
répondu Evgeniy B 2016-02-03 11:16:31

Vous pouvez analyser request_uri et remplacer vos paramètres régionaux dans le chemin par une expression régulière

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"

C'est un point de départ, donc vous pouvez faire des choses différentes dont vous avez besoin

2
répondu fl00r 2010-03-31 10:12:45

Jetez un oeil à ceci, bien qu'il ne soit pas sec et approprié, mais fonctionne parfaitement pour moi. Il lit tous les paramètres que vous avez fournis en remplaçant uniquement 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
répondu Santosh Bt 2012-06-14 08:38:25