代码之家  ›  专栏  ›  技术社区  ›  Faisal

rails链接到当前页面并向其传递参数

  •  46
  • Faisal  · 技术社区  · 16 年前

    通过使用url参数传递区域设置,我将i18n添加到rails应用程序中。我的网址看起来像 http://example.com/en/users http://example.com/ar/users (分别用于英语和阿拉伯语地区)。

    在我的路由文件中,我使用:path_前缀选项定义了我的路由:

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

    并且正在使用applicationcontroller中定义的before\u筛选器设置区域设置

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

    我还定义了applicationcontroller的默认url选项,以便将区域设置添加到由应用程序生成的所有url:

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

    我想要的是在布局标题中添加一个链接(显示在所有页面中),该链接将链接到同一页面,但具有其他区域设置。

    例如,如果我正在浏览阿拉伯语区域设置,我希望在标题中有一个“english”链接,该链接会将我重定向回当前页面,并将区域设置设置为english。在rails中有这样做的方法吗?

    5 回复  |  直到 10 年前
        1
  •  109
  •   pixelearth    16 年前

    我花了一段时间才找到这个,但这里是我的解决方案:

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

    从这里的文档: http://api.rubyonrails.org/classes/ActionController/Base.html#M000649

    生成新URL时,缺少 值可以从 当前请求参数。为了 例如,url_for:action=> 某些操作将保留当前 控制器,如预期。这种行为 扩展到其他参数,包括 :controller、:id和任何其他 放入 路线的路径。

    因此,使用url_for将默认为当前请求的参数,只需更改代码中所需的参数。在本例中,我只更改了:locale,所以其他内容都保持不变。

    注意,这也适用于“隐藏”:参数。如果你有:

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

    在页面/en/my_映射中使用上面的url_将不会在url中包含“home”(即/en/home/my_映射)。奖金。

        2
  •  14
  •   Will    14 年前

    所以我找到了一种更明确的方法,不用依赖(同样多的)rails魔术。

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

    这对任何 link_to .

    它所做的一切就是获取当前请求的参数,并将新的所需散列合并到这些参数中,然后为此创建一个新的url。

        3
  •  5
  •   Evgeniy B    10 年前

    链接到具有不同区域设置的当前页

    在轨道4上测试

    大家好。 经过一段时间的研究,我决定写我自己的解决方案。

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

    这很好,但它允许 XSS漏洞 只需在url中传递如下参数:

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

    或最坏情况:

    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
    

    查看在应用程序中浏览此链接后将获得的URL。

    我的生产解决方案。 方法“change language”仅使用请求对象中的http\u referer重定向到具有适当区域设置的任何页面。 请注意:uri.path方法用于仅获取路径,而不是整个url

    在任何控制器中使用“更改语言”方法:

            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
    

    应用程序控制器.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
    

    将此添加到布局中

    <%= link_to 'English', change_lang_path('en') %> <%= link_to 'Russian', change_lang_path('ru') %>
    

    配置/路由.rb

    scope "(:locale)", locale: /[a-zA-Z]{2}/ do
    get "change_lang/:lang" => "users#change_lang", :as => "change_lang"
    end
    

    不需要使用params.merge或任何monkey补丁解决方案。

    我希望这有帮助,因为我个人花了很多时间来解决它。

        4
  •  2
  •   fl00r    16 年前

    您可以解析请求uri,并用正则表达式替换路径中的区域设置

    好的,这是一个助手示例。如果我正确理解目标

    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"
    

    这是一个起点,所以你可以做一些你需要的不同的东西

        5
  •  1
  •   onurozgurozkan    14 年前

    看看这个,虽然它可能不干燥和适当的,但对我来说是完美的。它读取您提供的所有参数,仅替换区域设置 前网址: http://example.com:3000/us/users?t=123&m=343

      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