如何配置Rails路由以适应i18n

And*_*vey 7 ruby-on-rails internationalization

我正在向Rails应用程序添加国际化,并且或多或少地遵循相关的Rails指南Railscast.

我遇到了两个问题:

  1. 如何添加重定向到当前区域设置的"主页"链接.目前我有root_path链接,但由于routes.rb中的行设计用于获取未作用域的根,因此这些链接失败.这意味着root_path始终指向默认语言环境,而不是当前语言环境.
  2. 我已经在本地设置和工作(除了上面的问题),但部署到Heroku所有网址似乎都在我的路由文件中丢失并被其中一个捕获所有人抓住.它们在defulat语言环境下重定向到'/'.

我的设置如下

application_controller.rb

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

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

的routes.rb

scope ":locale", locale: /#{I18n.available_locales.join("|")}/  do
  all_my_routes

  # handles /valid-locale
  root to: 'home#index', as: "localized_root"
  # handles /valid-locale/fake-path
  match '*path', to: redirect { |params, request| "/#{params[:locale]}" }
end

# handles /
root to: redirect("/#{I18n.default_locale}")

# handles /bad-locale|anything/valid-path
match '/*locale/*path', to: redirect("/#{I18n.default_locale}/%{path}")

# handles /anything|valid-path-but-no-locale
match '/*path', to: redirect("/#{I18n.default_locale}/%{path}")
Run Code Online (Sandbox Code Playgroud)

我的主页链接:

<%= link_to "Home", root_path %>
Run Code Online (Sandbox Code Playgroud)

And*_*vey 8

经过一番来回,我最终得到了这个工作.问题在于捕获所有路径a)捕获的数量超出了我的预期,b)显然在开发与部署方面表现不同(为什么这应该是我不确定).

无论如何,首先我改变范围使其成为可选(注意括号):

scope "(:locale)", .....
Run Code Online (Sandbox Code Playgroud)

即使没有设置语言环境,这也确保了作用域路由有效(这主要是为了处理我遇到的回调等问题).

这让我可以放下两条root to线,只保留

root to "home#index"
Run Code Online (Sandbox Code Playgroud)

我删除了"handles/valid-locale/fake-path"行,这导致'/'路径出现问题.

然后在范围之后保留以下捕获全部(注意最后一个).

# handles /bad-locale|anything/valid-path
match '/*locale/*path', to: redirect("/#{I18n.default_locale}/%{path}")

# handles /anything|valid-path-but-no-locale
match '/*path', to: redirect("/#{I18n.default_locale}/%{path}"), constraints: lambda { |req| !req.path.starts_with? "/#{I18n.default_locale}/" }

# handles /
match '', to: redirect("/#{I18n.locale}")
Run Code Online (Sandbox Code Playgroud)

作为一个兴趣点,我还必须更新action_mailer来处理新的本地化网址.

config.action_mailer.default_url_options = { :host => 'path.to.my.app.com', :locale => I18n.locale }
Run Code Online (Sandbox Code Playgroud)

现在一切似乎都在起作用!


小智 6

有一颗宝石可以很好地完成这项工作.(https://github.com/svenfuchs/routing-filter)您应该将以下代码添加到您的Gemfile:

gem 'routing-filter'
Run Code Online (Sandbox Code Playgroud)

并将以下内容添加到routes.rb文件中

Rails.application.routes.draw do
  filter :locale
  ...
end
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你...


mah*_*ich 6

这篇博文实际上非常详细地解释了它:

正是我在寻找什么似乎没有任何作用

http://dhampik.com/blog/rails-routes-tricks-with-locales

  scope "/:locale", locale: /#{I18n.available_locales.join("|")}/ do
    resources :posts    
    root to: "main#index"
  end

  root to: redirect("/#{I18n.default_locale}", status: 302), as: :redirected_root

  get "/*path", to: redirect("/#{I18n.default_locale}/%{path}", status: 302), constraints: {path: /(?!(#{I18n.available_locales.join("|")})\/).*/}, format: false
Run Code Online (Sandbox Code Playgroud)

从root重定向到默认lang并执行许多其他操作.