Permalink
Browse files

[Sass Extensions] Allow the asset host and cache busting strategies t…

…o be defined as part of the compass configuration. Closes #20.
  • Loading branch information...
1 parent 885a85e commit ef47f3dd9dbfc087de8b12a90f9a82993bbb592e @chriseppstein chriseppstein committed Jun 26, 2009
View
@@ -1,7 +1,7 @@
module Compass
end
-['dependencies', 'sass_extensions', 'core_ext', 'version'].each do |file|
+['dependencies', 'sass_extensions', 'core_ext', 'version', 'errors'].each do |file|
require File.join(File.dirname(__FILE__), 'compass', file)
end
@@ -117,7 +117,41 @@ def css_path
end
end
+ # When called with a block, defines the asset host url to be used.
+ # The block must return a string that starts with a protocol (E.g. http).
+ # The block will be passed the root-relative url of the asset.
+ # When called without a block, returns the block that was previously set.
+ def asset_host(&block)
+ if block_given?
+ @asset_host = block
+ else
+ @asset_host
+ end
+ end
+
+ # When called with a block, defines the cache buster strategy to be used.
+ # The block must return nil or a string that can be appended to a url as a query parameter.
+ # The returned string must not include the starting '?'.
+ # The block will be passed the root-relative url of the asset.
+ # If the block accepts two arguments, it will also be passed a File object
+ # that points to the asset on disk -- which may or may not exist.
+ # When called without a block, returns the block that was previously set.
+ def asset_cache_buster(&block)
+ if block_given?
+ @asset_cache_buster = block
+ else
+ @asset_cache_buster
+ end
+ end
+
+
def serialize
+ if asset_cache_buster
+ raise Compass::Error, "Cannot serialize a configuration with asset_cache_buster set."
+ end
+ if asset_host
+ raise Compass::Error, "Cannot serialize a configuration with asset_host set."
+ end
contents = ""
required_libraries.each do |lib|
contents << %Q{require '#{lib}'\n}
@@ -179,6 +213,8 @@ def reset!
ATTRIBUTES.each do |attr|
send("#{attr}=", nil)
end
+ @asset_cache_buster = nil
+ @asset_host = nil
self.required_libraries = []
end
@@ -1,35 +1,51 @@
module Compass::SassExtensions::Functions::ImageUrl
def image_url(path)
path = path.value # get to the string value of the literal.
+ # Short curcuit if they have provided an absolute url.
if absolute_path?(path)
+ puts "#{path} is absolute"
return Sass::Script::String.new("url(#{path})")
end
- http_images_path = if Compass.configuration.http_images_path == :relative
+
+ # Compute the path to the image, either root relative or stylesheet relative
+ # or nil if the http_images_path is not set in the configuration.
+ http_images_path = if relative?
compute_relative_path
else
Compass.configuration.http_images_path
end
+ # Compute the real path to the image on the file stystem if the images_dir is set.
real_path = if Compass.configuration.images_dir
File.join(Compass.configuration.project_path, Compass.configuration.images_dir, path)
end
+ # prepend the path to the image if there's one
if http_images_path
http_images_path = "#{http_images_path}/" unless http_images_path[-1..-1] == "/"
path = "#{http_images_path}#{path}"
end
- if real_path && File.exists?(real_path)
- path += "?#{File.mtime(real_path).strftime("%s")}"
- elsif real_path
- $stderr.puts "WARNING: '#{File.basename(path)}' was not found in #{File.dirname(real_path)}"
+ # Compute the asset host unless in relative mode.
+ asset_host = (compute_asset_host(path) unless relative?)
+
+ # Compute and append the cache buster if there is one.
+ if buster = compute_cache_buster(path, real_path)
+ path += "?#{buster}"
end
+ # prepend the asset host if there is one.
+ path = "#{asset_host}#{'/' unless path[0..0] == "/"}#{path}" if asset_host
+
Sass::Script::String.new("url(#{path})")
end
private
+ def relative?
+ Compass.configuration.http_images_path == :relative
+ end
+
def absolute_path?(path)
path[0..0] == "/" || path[0..3] == "http"
end
@@ -40,4 +56,33 @@ def compute_relative_path
Pathname.new(images_path).relative_path_from(Pathname.new(File.dirname(target_css_file))).to_s
end
end
+
+ def compute_cache_buster(path, real_path)
+ if Compass.configuration.asset_cache_buster
+ args = [path]
+ if Compass.configuration.asset_cache_buster.arity > 1
+ args << (File.new(real_path) if real_path)
+ end
+ Compass.configuration.asset_cache_buster.call(*args)
+ elsif real_path
+ default_cache_buster(path, real_path)
+ end
+ end
+
+ def default_cache_buster(path, real_path)
+ if File.readable?(real_path)
+ File.mtime(real_path).strftime("%s")
+ else
+ $stderr.puts "WARNING: '#{File.basename(path)}' was not found (or cannot be read) in #{File.dirname(real_path)}"
+ end
+ end
+
+ def compute_asset_host(path)
+ if Compass.configuration.asset_host
+ Compass.configuration.asset_host.call(path)
+ else
+ nil
+ end
+ end
+
end
View
@@ -9,7 +9,7 @@ def setup
end
def teardown
- teardown_fixtures :blueprint, :yui, :empty, :compass
+ teardown_fixtures :blueprint, :yui, :empty, :compass, :image_urls
end
def teardown_fixtures(*project_names)
@@ -55,6 +55,15 @@ def test_compass
end
end
+ def test_image_urls
+ within_project('image_urls') do |proj|
+ each_css_file(proj.css_path) do |css_file|
+ assert_no_errors css_file, 'image_urls'
+ end
+ assert_renders_correctly :screen
+ end
+ end
+
private
def assert_no_errors(css_file, project_name)
file = css_file[(tempfile_path(project_name).size+1)..-1]
@@ -0,0 +1,17 @@
+# Require any additional compass plugins here.
+project_type = :stand_alone
+css_dir = "tmp"
+sass_dir = "sass"
+images_dir = "images"
+output_style = :compact
+# To enable relative image paths using the images_url() function:
+# http_images_path = :relative
+http_images_path = "/images"
+
+asset_cache_buster do |path, file|
+ "busted=true"
+end
+
+asset_host do |path|
+ "http://assets%d.example.com" % (path.hash % 4)
+end
@@ -0,0 +1 @@
+.showgrid { background-image: url(http://assets2.example.com/images/grid.png?busted=true); }
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,2 @@
+.showgrid
+ background-image= image_url("grid.png")

0 comments on commit ef47f3d

Please sign in to comment.