Rails link to current page and passing parameters to it

前端 未结 8 925

I am adding I18N to my rails application by passing the locale using url params. My urls are looking like http://example.com/en/users and http://example.com/ar/users (for th

相关标签:
8条回答
  • 2020-12-13 00:15

    Took me a while to find this but here is my solution:

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

    From the docs here: http://api.rubyonrails.org/classes/ActionController/Base.html#M000649

    When generating a new URL, missing values may be filled in from the current request‘s parameters. For example, url_for :action => ‘some_action‘ will retain the current controller, as expected. This behavior extends to other parameters, including :controller, :id, and any other parameters that are placed into a Route‘s path.

    So using url_for will default to the current request's parameters, just change the one's you want in your code. In this case all I changed was :locale, so everything else stays the same.

    Note this also works for "hidden" :parameters. So if you have:

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

    using the above url_for in the page /en/my_map will not have 'home' in the url (ie /en/home/my_map). Bonus.

    0 讨论(0)
  • 2020-12-13 00:22

    So I found a way to more explicitly do this with out relying on (as much) rails magic.

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

    This should work in any link_to.

    All its doing is taking the current request's parameters and merging your new desired hash into them and then creating a new url for that.

    0 讨论(0)
  • 2020-12-13 00:23

    Have a look at this, though it may not be DRY and proper one, but works perfectly for me. It reads all the parameters you supplied replacing only the locale 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
    
    0 讨论(0)
  • 2020-12-13 00:24

    Link to current page with different locales

    Tested on Rails 4

    Hello all. After some time of research I decide to write my own solution for this.

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

    This works perfect, but it allows XSS Vulnerability just passing parameters in your URL like below:

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

    Or worst case:

    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
    

    Check out what URLs you will get after going through this link in your application.

    My production solution. Method "change language" redirects to any page with proper locale just using HTTP_REFERER in request object. Please note: URI.path method for get only path, not whole url

    Make "change language" method in any controller:

            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
    

    add this to your 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
    

    There is no need to use params.merge or any monkey-patch solution.

    I hope this helps, because I personally spent a lot of time to solve it.

    0 讨论(0)
  • 2020-12-13 00:26

    A much quicker avenue - and convenient if you have many parameters that change in different places... avoid the clutter with an anchor tag that just merges the new locale param to the existing ones (and actually killing the old locale param).

    <%= link_to "ру", request.params.merge( locale: 'ru' ) %>
    

    But yes, one needs to whitelist parameters at that point, according to application's context.

    0 讨论(0)
  • 2020-12-13 00:28

    This is what worked for me, which preserves params and protects against xss:

    = link_to_unless_current "English", url_for( request.params.merge(locale: 'en'))
    

    You could use link_to instead of link_to_unless_current

    0 讨论(0)
提交回复
热议问题