Permalink
Browse files

moved SassOnHeroku to lib so it can be used from rack-based frameworks

  • Loading branch information...
pedro committed Jul 10, 2009
1 parent 4b942d3 commit f8e06d738429a5a905cd6b3e33b041b6748bb8f0
Showing with 74 additions and 75 deletions.
  1. +0 −75 init.rb
  2. +74 −0 lib/sass_on_heroku.rb
View
75 init.rb
@@ -1,76 +1 @@
-class SassOnHeroku
- def self.original_css_location
- @@original_css_location ||= nil
- end
-
- def self.original_css_location=(location)
- @@original_css_location = location
- end
-
- def initialize(app)
- @app = app
- initialize_sass unless self.class.original_css_location
- end
-
- def initialize_sass
- # get the original location of compiled css files (ie: stylesheets/compiled)
- # and replace it to a location in tmp
- if Sass::Plugin.options[:template_location].is_a?(Hash)
- self.class.original_css_location = Sass::Plugin.options[:template_location].values.first
- Sass::Plugin.options[:template_location].keys.each do |k|
- Sass::Plugin.options[:template_location][k] = css_location_on_heroku
- end
- else
- self.class.original_css_location = Sass::Plugin.options[:css_location]
- Sass::Plugin.options[:css_location] = css_location_on_heroku
- end
-
- # compile Sass once, and set it to not compile again
- Sass::Plugin.options[:always_update] = true
- Sass::Plugin.options[:never_update] = false
- Sass::Plugin.update_stylesheets
- Sass::Plugin.options[:never_update] = true
- end
-
- def call(env)
- if !stylesheets.empty? && env['REQUEST_PATH'] =~ css_request_regexp
- return render_sass($1)
- end
- @app.call(env)
- end
-
- def render_sass(name)
- css_file = "#{css_location_on_heroku}/#{name}"
- [
- 200,
- {
- 'Cache-Control' => 'public, max-age=86400',
- 'Content-Length' => File.size(css_file).to_s,
- 'Content-Type' => 'text/css'
- },
- File.read(css_file)
- ]
- end
-
- def css_location_on_heroku
- "#{RAILS_ROOT}/tmp/sass-output"
- end
-
- def stylesheets
- @stylesheets ||= Dir[css_location_on_heroku + '/*.css'].map { |f| f.split('/').last }
- end
-
- def css_request_regexp
- @css_request_regexp ||= build_regexp
- end
-
- # builds a regexp that matches requests for Sass stylesheets
- # ie : \/stylesheets\/sass\/(file1\.css|file2\.css)
- def build_regexp
- files = stylesheets.map { |f| Regexp.escape(f) }
- path = Regexp.escape(self.class.original_css_location.gsub("#{RAILS_ROOT}/public", '') + '/')
- regexp = Regexp.new("^#{path}(" + files.join('|') + ')(\?.*)?$')
- end
-end
-
ActionController::Dispatcher.middleware.use SassOnHeroku
View
@@ -0,0 +1,74 @@
+class SassOnHeroku
+ def self.original_css_location
+ @@original_css_location ||= nil
+ end
+
+ def self.original_css_location=(location)
+ @@original_css_location = location
+ end
+
+ def initialize(app)
+ @app = app
+ initialize_sass unless self.class.original_css_location
+ end
+
+ def initialize_sass
+ # get the original location of compiled css files (ie: stylesheets/compiled)
+ # and replace it to a location in tmp
+ if Sass::Plugin.options[:template_location].is_a?(Hash)
+ self.class.original_css_location = Sass::Plugin.options[:template_location].values.first
+ Sass::Plugin.options[:template_location].keys.each do |k|
+ Sass::Plugin.options[:template_location][k] = css_location_on_heroku
+ end
+ else
+ self.class.original_css_location = Sass::Plugin.options[:css_location]
+ Sass::Plugin.options[:css_location] = css_location_on_heroku
+ end
+
+ # compile Sass once, and set it to not compile again
+ Sass::Plugin.options[:always_update] = true
+ Sass::Plugin.options[:never_update] = false
+ Sass::Plugin.update_stylesheets
+ Sass::Plugin.options[:never_update] = true
+ end
+
+ def call(env)
+ if !stylesheets.empty? && env['REQUEST_PATH'] =~ css_request_regexp
+ return render_sass($1)
+ end
+ @app.call(env)
+ end
+
+ def render_sass(name)
+ css_file = "#{css_location_on_heroku}/#{name}"
+ [
+ 200,
+ {
+ 'Cache-Control' => 'public, max-age=86400',
+ 'Content-Length' => File.size(css_file).to_s,
+ 'Content-Type' => 'text/css'
+ },
+ File.read(css_file)
+ ]
+ end
+
+ def css_location_on_heroku
+ "#{RAILS_ROOT}/tmp/sass-output"
+ end
+
+ def stylesheets
+ @stylesheets ||= Dir[css_location_on_heroku + '/*.css'].map { |f| f.split('/').last }
+ end
+
+ def css_request_regexp
+ @css_request_regexp ||= build_regexp
+ end
+
+ # builds a regexp that matches requests for Sass stylesheets
+ # ie : \/stylesheets\/sass\/(file1\.css|file2\.css)
+ def build_regexp
+ files = stylesheets.map { |f| Regexp.escape(f) }
+ path = Regexp.escape(self.class.original_css_location.gsub("#{RAILS_ROOT}/public", '') + '/')
+ regexp = Regexp.new("^#{path}(" + files.join('|') + ')(\?.*)?$')
+ end
+end

2 comments on commit f8e06d7

@chriseppstein

This comment has been minimized.

Show comment Hide comment
@chriseppstein

chriseppstein Aug 18, 2009

Thanks, this is great stuff.

FYI: Setting all the css locations for the Sass::Plugin.options[:template_location] hash to the same location can result in sass files of the same names but in different output directories overwriting each other. It's probably not too likely, but I'd recommend against it. Instead, I think you should be able to remove "#{RAILS_ROOT}/public" from each and replace it with "#{RAILS_ROOT}/tmp/sass-output"

Thanks, this is great stuff.

FYI: Setting all the css locations for the Sass::Plugin.options[:template_location] hash to the same location can result in sass files of the same names but in different output directories overwriting each other. It's probably not too likely, but I'd recommend against it. Instead, I think you should be able to remove "#{RAILS_ROOT}/public" from each and replace it with "#{RAILS_ROOT}/tmp/sass-output"

@pedro

This comment has been minimized.

Show comment Hide comment
@pedro

pedro Aug 19, 2009

Contributor

Well thought! Thanks for your feedback, I'll fix that.

Contributor

pedro replied Aug 19, 2009

Well thought! Thanks for your feedback, I'll fix that.

Please sign in to comment.