Вы можете использовать классы в качестве пространств имен для контекста вашего CSS и JavaScript.
Например, если вы настроили свой макет следующим образом:
<!DOCTYPE html>
<html>
<head>
# ...
</head>
<% content_tag :body, class: [controller_name, action_name]
do %>
<%= yield %>
<% end %>
</html>
Это позволит вам создавать правила CSS, которые применяютсятолько к одному контроллеру и / или действию:
body.users h1 {
color: "blue"
}
body.users.show h1 {
color: "black"
}
И вы можете также охватить javascript, используя делегирование.
$('body.users').on('click', 'h1', function(){
alert("This works on any action for the users controller");
});
$('body.users.show').on('click', 'h1', function(){
alert("This should only work on the show view");
});
Вы можете применить этот же принцип к движку, создав помощникакоторый выводит тег body (или любой другой тег) с классами «scoping»:
# /lib/my_engine/helpers/tags_helper.rb
module MyEngine
module TagsHelper
def body_tag(**options, &block)
options[:class] ||= []
options[:class] << "my_engine" if controller.try(:my_engine_controller?)
content_tag(:body, options) { yield }
end
end
end
# /lib/my_engine/engine.rb
require 'helpers/tag_helper'
module MyEngine
class Engine < ::Rails::Engine
ActionView::Base.send :include, MyEngine::TagsHelper
end
end
Это предполагает, что контроллеры в вашем движке отвечают на my_engine_controller?
(как Devise делает с devise_controller?
.
Тогда это просто необходимо реализовать в макете:
<!DOCTYPE html>
<html>
<head>
# ...
</head>
<%= body_tag do %>
<%= yield %>
<% end %>
</html>
И вам нужно настроить ваши css / js на .my_engine
.