i18n Маршрутизация к установленному двигателю - Игнорирование локали
У меня есть приложение (my_test_app) с работающей поддержкой i18n. В настоящее время доступны два языковых файла, FR & EN, и если я переключаюсь между ними, все работает так, как я ожидаю, чтобы увидеть его для функций, не относящихся к движку, таких как User index/show/edit/delete (ISED) опции.
В my_test_app у меня установлен Rails Engine (my_engine), в котором установлен контроллер и модель (engine_job). Таким образом, работоспособный URL должен быть
http://0.0.0.0:3000/fr/my_engine/engine_job
Независимо от того, какой язык я выбираю, он всегда отображается на EN. Изучение параметров показывает:
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
locale: fr
action: index
controller: my_engine/engine_job
И все же выбранный перевод - EN.
my_test_app route.rb:
MyTestApp::Application.routes.draw do
scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
mount MyEngine::Engine, at: "/my_engine"
end # scope locale
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
my_engine route.rb:
MyEngine::Engine.routes.draw do
resources :my_jobs
end
Рейк-маршруты:
my_engine (/:locale)/my_engine MyEngine::Engine {:locale=>/en|fr/}
/*path(.:format) :controller#:action
/ :controller#:action
users GET (/:locale)/users(.:format) users#index {:locale=>/en|fr/}
POST (/:locale)/users(.:format) users#create {:locale=>/en|fr/}
new_user GET (/:locale)/users/new(.:format) users#new {:locale=>/en|fr/}
edit_user GET (/:locale)/users/:id/edit(.:format) users#edit {:locale=>/en|fr/}
user GET (/:locale)/users/:id(.:format) users#show {:locale=>/en|fr/}
PUT (/:locale)/users/:id(.:format) users#update {:locale=>/en|fr/}
DELETE (/:locale)/users/:id(.:format) users#destroy {:locale=>/en|fr/}
sessions POST (/:locale)/sessions(.:format) sessions#create {:locale=>/en|fr/}
new_session GET (/:locale)/sessions/new(.:format) sessions#new {:locale=>/en|fr/}
session DELETE (/:locale)/sessions/:id(.:format) sessions#destroy {:locale=>/en|fr/}
signup (/:locale)/signup(.:format) users#new {:locale=>/en|fr/}
signin (/:locale)/signin(.:format) sessions#new {:locale=>/en|fr/}
signout DELETE (/:locale)/signout(.:format) sessions#destroy {:locale=>/en|fr/}
help (/:locale)/help(.:format) static_pages#help {:locale=>/en|fr/}
about (/:locale)/about(.:format) static_pages#about {:locale=>/en|fr/}
root /(:locale)(.:format) static_pages#home {:locale=>/en|fr/}
Routes for MyEngine::Engine {:locale=>/en|fr/}:
engine_jobs GET /engine_jobs(.:format) my_engine/engine_jobs#index
POST /engine_jobs(.:format) my_engine/engine_jobs#create
new_engine_job GET /engine_jobs/new(.:format) my_engine/engine_jobs#new
edit_engine_job GET /engine_jobs/:id/edit(.:format) my_engine/engine_jobs#edit
engine_job GET /engine_jobs/:id(.:format) my_engine/engine_jobs#show
PUT /engine_jobs/:id(.:format) my_engine/engine_jobs#update
DELETE /engine_jobs/:id(.:format) my_engine/engine_jobs#destroy
Кроме того, любые ссылки, нажимаемые в Engine, устанавливают язык EN. Несколько поисковых запросов в Интернете не проливают реального света на то, что может происходить здесь, так как все примеры, которые я смог найти, не связаны с установленными двигателями.
РЕДАКТИРОВАТЬ: показать код для установки локали по умолчанию my_test_app / app / controllers / application_controller.rb:
class ApplicationController < ActionController::Base
protect_from_forgery
helper MyEngine::Engine.helpers
ActiveRecord::Base.verify_active_connections!
before_filter :set_locale
private
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
Rails.application.routes.default_url_options[:locale]= I18n.locale
logger.debug "My_Test_App: default_url_options is passed options: #{Rails.application.routes.default_url_options.inspect}\n"
# current_user.locale
# request.subdomain
# request.env["HTTP_ACCEPT_LANGUAGE"]
# request.remote_ip
end # set_locale
end # class ApplicationController
/РЕДАКТИРОВАТЬ
РЕДАКТИРОВАТЬ 2 (Карта маршрута после изменений, предложенных Пьером 9 августа в 15:59):
Маршрут приложения приводит к http://0.0.0.0:3000/en/users
с "locale"=>"en"
, Созданный помощником маршрут двигателя выглядит так http://0.0.0.0:3000/my_engine?locale=en/engine_jobs
и дает No route matches [GET] "/my_engine"
,
my_engine_plugin /my_engine MyEnginePlugin::Engine
users GET (/:locale)/users(.:format) users#index {:locale=>/en|fr/}
POST (/:locale)/users(.:format) users#create {:locale=>/en|fr/}
new_user GET (/:locale)/users/new(.:format) users#new {:locale=>/en|fr/}
edit_user GET (/:locale)/users/:id/edit(.:format) users#edit {:locale=>/en|fr/}
user GET (/:locale)/users/:id(.:format) users#show {:locale=>/en|fr/}
PUT (/:locale)/users/:id(.:format) users#update {:locale=>/en|fr/}
DELETE (/:locale)/users/:id(.:format) users#destroy {:locale=>/en|fr/}
sessions POST (/:locale)/sessions(.:format) sessions#create {:locale=>/en|fr/}
new_session GET (/:locale)/sessions/new(.:format) sessions#new {:locale=>/en|fr/}
session DELETE (/:locale)/sessions/:id(.:format) sessions#destroy {:locale=>/en|fr/}
signup (/:locale)/signup(.:format) users#new {:locale=>/en|fr/}
signin (/:locale)/signin(.:format) sessions#new {:locale=>/en|fr/}
signout DELETE (/:locale)/signout(.:format) sessions#destroy {:locale=>/en|fr/}
help (/:locale)/help(.:format) static_pages#help {:locale=>/en|fr/}
about (/:locale)/about(.:format) static_pages#about {:locale=>/en|fr/}
root /(:locale)(.:format) static_pages#home {:locale=>/en|fr/}
Routes for MyEnginePlugin::Engine:
engine_jobs GET (/:locale)/engine_jobs(.:format) my_engine_plugin/engine_jobs#index {:locale=>/en|fr/}
POST (/:locale)/engine_jobs(.:format) my_engine_plugin/engine_jobs#create {:locale=>/en|fr/}
new_engine_job GET (/:locale)/engine_jobs/new(.:format) my_engine_plugin/engine_jobs#new {:locale=>/en|fr/}
edit_engine_job GET (/:locale)/engine_jobs/:id/edit(.:format) my_engine_plugin/engine_jobs#edit {:locale=>/en|fr/}
engine_job GET (/:locale)/engine_jobs/:id(.:format) my_engine_plugin/engine_jobs#show {:locale=>/en|fr/}
PUT (/:locale)/engine_jobs/:id(.:format) my_engine_plugin/engine_jobs#update {:locale=>/en|fr/}
DELETE (/:locale)/engine_jobs/:id(.:format) my_engine_plugin/engine_jobs#destroy {:locale=>/en|fr/}
/EDIT2 (Карта маршрутов после изменений, предложенных Пьером 9 августа в 15:59)
Итак, вопрос в том, какие изменения мне нужно внести в мои маршруты или движок, чтобы заставить это работать так, как ожидалось?
Заранее спасибо за ваше время и предложения!
1 ответ
Я использую Engine с I18n, и он работает нормально. Я создал фиктивное приложение Rails, чтобы попробовать ваш сценарий. Насколько я знаю, изменение локали внутри URL прекрасно работает с маршрутами, определенными в вашем приложении Rails:
Мои маршруты:
Bar::Application.routes.draw do
root 'posts#index'
scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
resources :posts, only: :index
end
end
Я могу изменить локаль I18n с помощью:
http://localhost:3000/fr/posts
http://localhost:3000/en/posts
Я думаю, что ваша проблема в том, что вы хотите перейти на любой из маршрутов вашего движка, поскольку вы не установили переключатель языка I18n. Смотрите ниже:
engine_jobs GET /engine_jobs(.:format)
Затем, когда собираюсь /engine_jobs
даже если вы указали языковой стандарт в URL, это будет языковой стандарт по умолчанию (18)en
):
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
# ...
end
При использовании маршрутов вашего двигателя, params[:locale]
является nil
Решение
Добавьте ту же логику к маршрутам вашего движка:
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"
только говорит рельсам "загрузить" все маршруты двигателя. Если вам нужно добавить ограничения, области, пространство имен или что-то еще, вы должны использовать обычный способ rails, но в файле маршрутов вашего движка.
Наконец, вам нужно обновить оба ваших application_controller.rb
(основное приложение + движок) со следующим:
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