Limit CSS and JS to Rails Engine












0














I have created a Rails Engine and its CSS and Javascript are changing the host application layout.



Is there a way of confining the assets to the Engine Views without changing the entire application?










share|improve this question





























    0














    I have created a Rails Engine and its CSS and Javascript are changing the host application layout.



    Is there a way of confining the assets to the Engine Views without changing the entire application?










    share|improve this question



























      0












      0








      0







      I have created a Rails Engine and its CSS and Javascript are changing the host application layout.



      Is there a way of confining the assets to the Engine Views without changing the entire application?










      share|improve this question















      I have created a Rails Engine and its CSS and Javascript are changing the host application layout.



      Is there a way of confining the assets to the Engine Views without changing the entire application?







      javascript css ruby-on-rails rails-engines






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 20 at 17:45

























      asked Nov 20 at 17:09









      Miguel Torres

      112




      112
























          1 Answer
          1






          active

          oldest

          votes


















          0














          You can use classes as namespaces to scope your css and javascript.



          For example if you setup your layout as so:



          <!DOCTYPE html>
          <html>
          <head>
          # ...
          </head>
          <% content_tag :body, class: [controller_name, action_name]
          do %>
          <%= yield %>
          <% end %>
          </html>


          This will let you create CSS rules that apply to only one controller and or action:



          body.users h1 {
          color: "blue"
          }

          body.users.show h1 {
          color: "black"
          }


          And you can scope javascript as well by using delegation.



          $('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");
          });


          You can apply this same principle to an engine by creating a helper which outputs a body tag (or any tag really) with "scoping" classes:



          # /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


          This assumes that the controllers in your engine respond to my_engine_controller?(like Devise does with the devise_controller?.



          Then it just needs to implemented in the layout:



          <!DOCTYPE html>
          <html>
          <head>
          # ...
          </head>
          <%= body_tag do %>
          <%= yield %>
          <% end %>
          </html>


          And you need to scope your css/js to .my_engine.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53398080%2flimit-css-and-js-to-rails-engine%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            You can use classes as namespaces to scope your css and javascript.



            For example if you setup your layout as so:



            <!DOCTYPE html>
            <html>
            <head>
            # ...
            </head>
            <% content_tag :body, class: [controller_name, action_name]
            do %>
            <%= yield %>
            <% end %>
            </html>


            This will let you create CSS rules that apply to only one controller and or action:



            body.users h1 {
            color: "blue"
            }

            body.users.show h1 {
            color: "black"
            }


            And you can scope javascript as well by using delegation.



            $('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");
            });


            You can apply this same principle to an engine by creating a helper which outputs a body tag (or any tag really) with "scoping" classes:



            # /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


            This assumes that the controllers in your engine respond to my_engine_controller?(like Devise does with the devise_controller?.



            Then it just needs to implemented in the layout:



            <!DOCTYPE html>
            <html>
            <head>
            # ...
            </head>
            <%= body_tag do %>
            <%= yield %>
            <% end %>
            </html>


            And you need to scope your css/js to .my_engine.






            share|improve this answer




























              0














              You can use classes as namespaces to scope your css and javascript.



              For example if you setup your layout as so:



              <!DOCTYPE html>
              <html>
              <head>
              # ...
              </head>
              <% content_tag :body, class: [controller_name, action_name]
              do %>
              <%= yield %>
              <% end %>
              </html>


              This will let you create CSS rules that apply to only one controller and or action:



              body.users h1 {
              color: "blue"
              }

              body.users.show h1 {
              color: "black"
              }


              And you can scope javascript as well by using delegation.



              $('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");
              });


              You can apply this same principle to an engine by creating a helper which outputs a body tag (or any tag really) with "scoping" classes:



              # /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


              This assumes that the controllers in your engine respond to my_engine_controller?(like Devise does with the devise_controller?.



              Then it just needs to implemented in the layout:



              <!DOCTYPE html>
              <html>
              <head>
              # ...
              </head>
              <%= body_tag do %>
              <%= yield %>
              <% end %>
              </html>


              And you need to scope your css/js to .my_engine.






              share|improve this answer


























                0












                0








                0






                You can use classes as namespaces to scope your css and javascript.



                For example if you setup your layout as so:



                <!DOCTYPE html>
                <html>
                <head>
                # ...
                </head>
                <% content_tag :body, class: [controller_name, action_name]
                do %>
                <%= yield %>
                <% end %>
                </html>


                This will let you create CSS rules that apply to only one controller and or action:



                body.users h1 {
                color: "blue"
                }

                body.users.show h1 {
                color: "black"
                }


                And you can scope javascript as well by using delegation.



                $('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");
                });


                You can apply this same principle to an engine by creating a helper which outputs a body tag (or any tag really) with "scoping" classes:



                # /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


                This assumes that the controllers in your engine respond to my_engine_controller?(like Devise does with the devise_controller?.



                Then it just needs to implemented in the layout:



                <!DOCTYPE html>
                <html>
                <head>
                # ...
                </head>
                <%= body_tag do %>
                <%= yield %>
                <% end %>
                </html>


                And you need to scope your css/js to .my_engine.






                share|improve this answer














                You can use classes as namespaces to scope your css and javascript.



                For example if you setup your layout as so:



                <!DOCTYPE html>
                <html>
                <head>
                # ...
                </head>
                <% content_tag :body, class: [controller_name, action_name]
                do %>
                <%= yield %>
                <% end %>
                </html>


                This will let you create CSS rules that apply to only one controller and or action:



                body.users h1 {
                color: "blue"
                }

                body.users.show h1 {
                color: "black"
                }


                And you can scope javascript as well by using delegation.



                $('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");
                });


                You can apply this same principle to an engine by creating a helper which outputs a body tag (or any tag really) with "scoping" classes:



                # /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


                This assumes that the controllers in your engine respond to my_engine_controller?(like Devise does with the devise_controller?.



                Then it just needs to implemented in the layout:



                <!DOCTYPE html>
                <html>
                <head>
                # ...
                </head>
                <%= body_tag do %>
                <%= yield %>
                <% end %>
                </html>


                And you need to scope your css/js to .my_engine.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 20 at 19:42

























                answered Nov 20 at 19:23









                max

                44.5k857103




                44.5k857103






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53398080%2flimit-css-and-js-to-rails-engine%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Wiesbaden

                    Marschland

                    Dieringhausen