4

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.

DVG
  • 17,392
  • 7
  • 61
  • 88
  • Do you have "*= require_tree ." somewhere in your app/assets/stylesheets/application.css? If not, try adding it, might help. – rootless Jul 07 '14 at 14:44
  • As explained, there are assets outside the scope of the full application that need to be precompiled and included individually. – DVG Jul 07 '14 at 14:54
  • All the three example file paths don't seem to be "outside the scope of the full application" (if that means "outside the application's directory tree"). Actually, they should be picked up by asset precompilation by default, because they're in app/assets (if require_tree is present in your application.css). I guess I got something wrong. – rootless Jul 07 '14 at 16:48
  • Asset precompilation does not pick up any js or css files (or files that will be processed into js or css files) except those included in application.js or application.css. I do not wish for these files to be included in those files, and instead be compiled and available for running `<%= javascript_include_tag 'page-specific/thingie" %>` – DVG Jul 07 '14 at 18:05

2 Answers2

3

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

Unihedron
  • 10,902
  • 13
  • 62
  • 72
1

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.

rootless
  • 1,348
  • 1
  • 10
  • 11