Rails链接到当前页面并将参数传递给它

Fai*_*sal 47 ruby-on-rails internationalization

我通过使用url params传递语言环境,将I18N添加到我的rails应用程序中.我的网址看起来像http://example.com/en/usershttp://example.com/ar/users(分别针对英语和阿拉伯语语言环境).

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

map.resources :users, :path_prefix => '/:locale'
Run Code Online (Sandbox Code Playgroud)

并且使用ApplicationController中定义的before_filter设置locale

def set_locale
    I18n.locale = params[:locale]
end
Run Code Online (Sandbox Code Playgroud)

我还定义了ApplicationController#default_url_options,将语言环境添加到应用程序生成的所有URL:

def default_url_options(options={})
    {:locale => I18n.locale}
end
Run Code Online (Sandbox Code Playgroud)

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

例如,如果我正在浏览阿拉伯语语言环境,我希望标题中有一个"英语"链接,它会将我重定向回当前页面,并将语言环境设置为英语.有没有办法在rails中执行此操作?

pix*_*rth 111

我花了一段时间才发现这个,但这是我的解决方案:

link_to 'English', url_for( :locale => 'en' )
link_to 'Deutch', url_for( :locale => 'de' ) 
Run Code Online (Sandbox Code Playgroud)

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

生成新URL时,可以从当前请求的参数中填入缺失值.例如,url_for:action =>'some_action'将按预期保留当前控制器.此行为扩展到其他参数,包括:controller,:id以及放置在Route路径中的任何其他参数.

因此,使用url_for将默认为当前请求的参数,只需在代码中更改所需的参数即可.在这种情况下,我改变的是:locale,所以其他一切都保持不变.

请注意,这也适用于"隐藏":参数.所以如果你有:

map.my_map ':locale/my_map', :controller => 'home', :action => 'my_map'
Run Code Online (Sandbox Code Playgroud)

使用页面/ en/my_map中的上述url_for将不会在url中具有"home"(即/ en/home/my_map).奖金.

  • 如果您想要抑制语言环境:url_for(:locale => nil) (2认同)

Wil*_*ill 13

所以我找到了一种更明确地做到这一点的方法,而不依赖于(尽可能多)rails magic.

url_for(params.merge({:your_new_parameter => value}))
Run Code Online (Sandbox Code Playgroud)

这应该适用于任何link_to.

它所做的就是获取当前请求的参数并将新的所需哈希值合并到它们中,然后为此创建一个新的URL.

  • 此解决方案公开所有参数,甚至是那些使用POST发送的参数,例如密码.请不要使用它. (4认同)

小智 5

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

在Rails上测试4

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

link_to 'English', url_for( :locale => 'en' )
link_to 'Deutch', url_for( :locale => 'de' ) 
Run Code Online (Sandbox Code Playgroud)

这很完美,但它允许XSS漏洞只是在URL中传递参数,如下所示:

http://localhost:3000/en/about?host=www.fishingsiteorbadurl.com/%23&port=80
Run Code Online (Sandbox Code Playgroud)

或者最坏的情况:

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
Run Code Online (Sandbox Code Playgroud)

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

我的生产解决方案 方法"更改语言"仅使用请求对象中的HTTP_REFERER重定向到具有适当区域设置的任何页面. 请注意:URI.path方法只获取路径,而不是整个网址

在任何控制器中制作"更改语言"方法:

        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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

将其添加到您的布局中

<%= link_to 'English', change_lang_path('en') %> <%= link_to 'Russian', change_lang_path('ru') %>
Run Code Online (Sandbox Code Playgroud)

配置/ routes.rb中

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

没有必要使用params.merge或任何猴子补丁解决方案.

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