i18n Routing To Mounted Engine - Ignoring locale

六眼飞鱼酱① 提交于 2019-11-29 04:32:25

I am using Engine with I18n and it works fine. I created a dummy Rails application to try your scenario. As far as I know, changing the locale inside the URL works fine with routes defined in your Rails application:

My routes:

Bar::Application.routes.draw do
  root 'posts#index'

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

I am able to change the I18n locale with:

http://localhost:3000/fr/posts
http://localhost:3000/en/posts

I think that your probleme is when you want to go to any of your engine's routes since you did not set the I18n locale switch. See bellow:

engine_jobs GET    /engine_jobs(.:format)

Then, when going to /engine_jobs even if you specified a locale in the URL, it's I18n default locale that will be set (en):

def set_locale
  I18n.locale = params[:locale] || I18n.default_locale
  # ...
end

When using your Engine routes, params[:locale] is nil

Solution

Add the same logic to your engine's routes:

config/routes.rb

MyTestApp::Application.routes.draw do

  mount MyEngine::Engine, at: "/my_engine"

  match '*path', to: redirect("/#{I18n.default_locale}/%{path}"), constraints: lambda { |req| !req.path.starts_with? "/#{I18n.default_locale}/" and !req.path == "/#{I18n.default_locale}/"}
  match '', to: redirect("/#{I18n.default_locale}/")
end

your_engine/config/routes.rb

MyEngine::Engine.routes.draw do
  scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
    resources :my_jobs
  end
end

mount MyEngine::Engine, at: "/my_engine" only tells rails to "load" all engine routes. If you need to add constraints, scopes, namespace or anything else, you should use usual rails way to do it but in your engine's routes file.

Finally you need to update both of your application_controller.rb (main app + engine) with the following:

class ApplicationController < ActionController::Base
  def url_options
    { locale: I18n.locale }
  end

  def set_locale
    I18n.locale = params[:locale] || I18n.default_locale
    Rails.application.routes.default_url_options[:locale]= I18n.locale
  end
end
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!