Rails的链接,当前页面和参数传递给它
-
23-09-2019 - |
题
我通过传递使用网址参数的语言环境国际化添加到我的Rails应用程序。我的网址正在寻找像 http://example.com/en/users 和的 http://example.com/ar/users (分别为英语,阿拉伯语的语言环境)
在我的路由文件,我已经定义我的路线用:选择串流中:
map.resources :users, :path_prefix => '/:locale'
和语言环境正在使用的ApplicationController定义的设置的before_filter
def set_locale
I18n.locale = params[:locale]
end
我还定义的ApplicationController#default_url_options,区域设置添加到由应用程序生成的所有URL:
def default_url_options(options={})
{:locale => I18n.locale}
end
我要的是增加在布局标题(在所有页面中显示),这将链接到同一页面,但与其他区域的链接。
举例来说,如果我在浏览阿拉伯语的语言环境,我想在头一个“英语”链接,将重定向我回到我的当前页面,以及区域设置为英语。有没有办法在轨做到这一点?
解决方案
我花了一段时间来找到这一点,但这里是我的解决方案:
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:动作=> “some_action”将保留当前 控制器,如所预期。此行为 延伸到其他参数,包括 :控制器,:ID,以及任何其它 被放置成一个参数 路由的路径。
因此,使用url_for将默认为当前请求的参数,只是改变了一个人的,你在你的代码需要。在这种情况下,所有我改变的是:语言环境,让一切保持不变。
请注意,这也适用于“隐藏”:参数。所以,如果你有:
map.my_map ':locale/my_map', :controller => 'home', :action => 'my_map'
使用上述url_for在页面/ EN / my_map不会有在url(即/ EN /家庭/ my_map) '家'。奖金。
其他提示
于是,我找到了一种方法,以更明确地用了依靠(多)做到这一点轨魔法。
url_for(params.merge({:your_new_parameter => value}))
此应该在任何link_to
工作。
所有公司做的是当前请求的参数,并合并新的期望的散列放进去,然后,创建一个新的URL。
链接与不同的区域设置当前网页强>
测试上轨道4
您好所有。 经过研究一段时间,我决定写我自己的这个解决方案。
link_to 'English', url_for( :locale => 'en' )
link_to 'Deutch', url_for( :locale => 'de' )
这完美的作品,但它允许 XSS漏洞只是路过参数在你的网址,如下所示:
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。
我生产溶液。强> 方法“更改语言”重定向到任何页面,正确的语言环境只使用在HTTP_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
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
添加到您的布局
<%= link_to 'English', change_lang_path('en') %> <%= link_to 'Russian', change_lang_path('ru') %>
配置/ routes.rb中
scope "(:locale)", locale: /[a-zA-Z]{2}/ do
get "change_lang/:lang" => "users#change_lang", :as => "change_lang"
end
有不需要使用params.merge或任何猴子补丁溶液。
我希望这可以帮助,因为我个人花了大量的时间来解决这个问题。
您可以解析REQUEST_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"
这是一个起点,这样你就可以做一些不同的东西,你需要
看一看这一点,虽然它可能不是干燥,适当的,但完美的作品对我来说。它读取你提供的仅替换区域的所有参数 EX网址: http://example.com:3000/us/users?t= 123米= 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
有一个更快的途径 - 和方便,如果你有很多参数,这些参数在不同的地方变化......避免与刚刚合并的新的语言环境参数去了现有的锚标记杂波(和实际杀害老区域PARAM)
<%= link_to "ру", request.params.merge( locale: 'ru' ) %>