DVG
DVG

Reputation: 17480

Rails 3 - Precompiling all css, sass and scss files in a folder

So I have a project with page-specific styles and css. I've put those files into their own directory assets/#{type}/page-specific/ and I'm attempting to write a regex rule to inform the precompiler to do it's thing with them.

This is working great for the JS side of the house, but the css is proving more difficult.

# page specific style files:
app/assets/stylesheets/page-specific/something.css.sass
app/assets/stylesheets/page-specific/default.css
app/assets/stylesheets/page-specific/home.css.scss

I was working with this regex in my config/initializers/assets.rb file:

Rails.application.config.assets.precompile << /(page-specific\/[^(css)]+.css)/

The problem being that the [^(css)] section doesn't do quite what I want, as it will filter out anything that has a c or s in it. What I'm really looking for is a way to match up to the whole string "css" and stop there.

Also, I know the conventional wisdom would be to simply write the styles in a way that you wouldn't need page-specific stylesheets in favor of application.css containing the whole of the stylesheets. I agree. However this is a very large code base and there is a lot of time pressure to bring this Rails upgrade home, and there isn't time to spend analyzing and refactoring things of this nature.

I've tried just making the delimiter directive [^\.] to stop at the first dot, however this blows up on some vendor stylesheets that use the dot as a delimiter such as jquery.treeview.css.sass. Obviously I can just change the file names, but we are a large team that's growing, and I want to make the rule as flexible as possible so we don't have files sneak in that will blow up in production when they don't get precompiled.

Upvotes: 4

Views: 1761

Answers (2)

Unihedron
Unihedron

Reputation: 11051

This answer is specifically for the regex. You're looking for "absence of character sequence css" in place of [^(css)].


This regex takes a similar approach to yours:

/(page-specific\/(?:(?!\.css).)++\.css)/

Explanation:

  • page-specific\/ matches the character sequence "page-specific/" literally.
  • (?: opens a non-capturing group.
    • (?!\.css) asserts that the current index is not of character sequence ".css".

If this assertion fails at the first time this group is matched, the current section will fail to be matched (page-specific/.css is no good), else this terminates group quantification as we've already matched .css, and returns to \.css)/ to finish.

    • . matches anything except for newline.
  • )++ closes the group and quantifies to unlimited times possessively (Without giving back).
    Note: Ruby supports possessive quantifiers starting with Ruby 1.9.
  • \.css matches the character sequence ".css" literally.

visualization

Read more:


However if nothing, this regex does it with a nongreedy modifier:

/(page-specific\/.+?\.css)/

As .+? matches as few times as possible, the resulting capture is guaranteed to end at the first .css.

visualization

Read more:


PS: You may have forgotten to escape a dot near the end of your regex in .css/.


Specified by:
http://www.tutorialspoint.com/ruby/ruby_regular_expressions.htm

Upvotes: 3

rootless
rootless

Reputation: 1388

OK, I think I get it now. Suppose you have these two files:

app/assets/stylesheets/page-specific/default.css
app/assets/stylesheets/page-specific/more-specific/home.css.scss

After you add this to your config/initializers/assets.rb

Rails.application.config.assets.paths << Rails.root.join('app', 'assets', 'stylesheets', 'page-specific')
Rails.application.config.assets.precompile << /.+\.css$/

Please note that this should work even for directories outside 'app/assets' (of course, you'll need to modify the path that gets added to config.assets.paths).

You should be able to reference them in your ERB pages like this:

  <%= stylesheet_link_tag 'default', media: 'all' %>
  <%= stylesheet_link_tag 'more-specific/home', media: 'all' %>

I hope this helps.

Upvotes: 1

Related Questions