3

I have YooTheme and Bootstrap and they are interfering with each other. The designer used YooTheme for the home page and I don't have time to translate it. How do I include yootheme.css only for the index page, and exclude it from the header everywhere else? I have

application.haml - Layout
/ UIkit CSS
-# %link{:rel => "stylesheet", :href => "https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.30/css/uikit.min.css"}/
%link{:rel => "stylesheet", :crossorigin => "anonymous", :href => "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css", :integrity => "sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ"}/
= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' 
application.scss
 *= require_tree .
 *= require_self

app/assets/stylesheets/yootheme.css

index.haml
=stylesheet_link_tag 'yootheme.css', media: :all

4 Answers 4

4

You can use sprockets#stub and the filename to exclude in your application.css file, in order to prevent its load:

*= stub yootheme.css

And then to incorporate it manually, you have to add the file to your assets.rb, restart your server, and load the file by yourself using the stylesheet_link_tag helper:

# config/initializers/assets.rb
# Rails.application.config.assets.precompile += %w( yootheme.css )

# view
= stylesheet_link_tag 'yootheme.css', media: :all
Sign up to request clarification or add additional context in comments.

2 Comments

Nifty - but your should avoid sprockets directives in SASS/SCSS as they don't play nice with the Sass compiler. I also really don't see how this would be worked into a compile on deployment setup.
Or do you leave the *= stub yootheme.css directive in there and is the restart to trigger assets recomplilation?
3

Don't use require_tree in SASS/SCSS

Sprockets provides some directives that are placed inside of comments called require, require_tree, and require_self. DO NOT USE THEM IN YOUR SASS/SCSS FILES. They are very primitive and do not work well with Sass files. Instead, use Sass's native @import directive which sass-rails has customized to integrate with the conventions of your Rails projects. https://github.com/rails/sass-rails

If you are not using any Sass features such as variables, functions, mixins etc you'll get by fine with require_tree. But soon as you do you will realize that they are not available in any file except in the one they are declared. Thats because each file is run in the SASS compiler before Sprockets concatenates the files together.

So you are better off using @import 'foo' and manually declaring which files and the order they should be added to the compiled stylesheet.

Its not as bad as it sounds

The default assets pipeline setup is a pretty good attempt to get lazy programmers not to shove everything into a single css/js file while still compiling it to single optimized file. It really requires require_tree . to make sense.

I usually turn off the assets generator:

# config/application.rb
module MyApp
  class Application < Rails::Application
    config.generators do |g|
      g.assets false
      # or
      g.stylesheets false
    end
  end
end

Instead I deliberately organize the code in app/assets into modules. And any code that is not mine goes into /vendor.

You can use glob imports to import sass mixins and varibles from library folders - but it cannot/should not replace require_tree.

Using content_for instead of separate layouts

Using a seperate layout means that you have to duplicate the entire file just to change a line or two.

Instead you can use content_for to make dynamic chunks in a layout:

# application.html.haml:
!!!
%html
  %head
    %title My Rails app
    - content_for :assets
      = stylesheet_link_tag "application"
      = javascript_include_tag "application"
    = csrf_meta_tag

  %body
    = yield

Then later in the index template we can add to the head section:

- content_for :assets
  = stylesheet_link_tag "some_other_file"

This would add the stylesheet link under = javascript_include_tag "application" as content_for concatenates the provided block to the content that is already captured. Use flush: true to discard any previously provided content (by the layout).

- content_for :assets, flush: true
  = stylesheet_link_tag "some_other_file"

2 Comments

Even if you are not using sass the greedy require_tree directive in sprockets offers no control over how files are included (its alphabetically). In CSS thats bullocks as directives have priority in the order they are defined. So my real take away is beware of require_tree.
"Thats because each file is run in the SASS compiler before Sprockets concatenates the files together." That explains why I have to repeat @import "colors.scss"; in all my files.
0

something like this

index.haml(layout) ..

- if action_name=="index"
   /* include both application.css and yootheme.css for index*/
   = stylesheet_link_tag 'application', 'yootheme.css', media: :all
- else
   /* include only application.css*/
   =stylesheet_link_tag 'application, media: :all

2 Comments

Both layouts will still have stylesheet_link_tag 'application' and it will still include yootheme.css. How do I exclude yootheme.css?
@Chloe check above answer. You can do action based asset loading
-1

scss_files: 'app/assets/stylesheets/**/*.css.scss'

exclude: 'app/assets/stylesheets/plugins/**'

linters: BorderZero: enabled: false

Indentation: exclude: - 'path/to/file.scss' - 'path/to/directory/**' severity: warning width: 2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.