我正在研究Rails 3.1应用程序,我想为应用程序支持的不同语言设置特定路由。
/es/countries
/de/countries
…
对于默认语言('en'),我不希望语言环境显示在网址中。
/countries
这是我设定的路线定义。
scope "(:locale)", :locale => /es|de/ do
resources :countries
end
它非常有用,直到我尝试使用带有'en'的路径助手作为语言环境。
在控制台中:
app.countries_path(:locale => 'fr')
=> "/fr/countries"
app.countries_path(:locale => 'en')
=> "/countries?locale=en"
我不想要“?locale = en”。
有没有办法告诉rails使用'en'语言环境,不应该将语言环境参数添加到网址?
由于
答案 0 :(得分:21)
这应该是一个更好的解决方案:
在你的routes.rb中,
scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/, defaults: {locale: "en"} do
正如MegaTux所说,在范围内设置defaults: {locale: "en"}
。
优点:
jlfenaux解决方案适用于大多数情况,但不是全部。在某些上下文中(基本上是主控制器和视图之外的任何内容),路径助手会混淆并将对象或object.id放在locale
参数中,这将导致错误。您会发现自己将locale: nil
放在许多路径助手中以避免这些错误。
可能存在的问题:
defaults: {locale: "en"}
似乎总是覆盖您传递给locale
的任何其他值。该选项名为default
,因此我希望它将区域设置分配给' en'只有在没有价值的情况下,才会发生这种情况。有其他人经历过这个吗?
答案 1 :(得分:16)
我终于想出了如何轻松地做到这一点。您只需在app控制器中设置default_url_options,如下所示。
def default_url_options(options={})
{ :locale => I18n.locale == I18n.default_locale ? nil : I18n.locale }
end
这样,您确定区域设置不会发送到路径助手。
答案 2 :(得分:3)
如果您不想要查询字符串,则不必将其传递给帮助程序:
1.9.2 (main):0 > app.countries_path(:locale=>:de)
=> "/de/countries"
1.9.2 (main):0 > app.countries_path
=> "/countries"
1.9.2 (main):0 > app.countries_path(:locale=>:en)
=> "/countries?locale=en"
1.9.2 (main):0 > app.countries_path
=> "/countries"
1.9.2 (main):0 > app.countries_path(:locale=>nil)
=> "/countries"
答案 3 :(得分:3)
我正在做@Arcolye和@jifenaux正在做的事情的组合,加上一些额外的东西来保持代码尽可能干。它可能不适合所有人,但在我的情况下,每当我想支持新的语言环境时,我还必须在.yml
中创建一个新的config/locales/
文件,所以这就是它最适合的方式。我
locale_files = Dir["#{Rails.root}/config/locales/??.yml"]
config.i18n.available_locales = locale_files.map do |d|
d.split('/').last.split('.').first
end
config.i18n.default_locale = :en
root_path = 'pages#welcome'
scope '(:locale)', locale: /#{I18n.available_locales.join('|')}/ do
# ...
end
root to: root_path
get '/:locale', to: root_path
private
def default_url_options(options = {})
if I18n.default_locale != I18n.locale
{locale: I18n.locale}.merge options
else
{locale: nil}.merge options
end
end
答案 4 :(得分:0)
如果您决定将default_url_options
放入application_controller
来修复路径助手,请记住您可能还想将其放入管理员的application_contoller中
答案 5 :(得分:0)
就我而言,我使用以下技术解决了此问题:
class ApplicationController < ActionController::Base
layout -> {
if devise_controller?
'devise'
end
}
before_action :set_locale
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
def url_options
{ :locale => I18n.locale }.merge(super)
end
end