Sass Image CSS Cache Busting (Via Compass)

sass cache busting

Thanks Dawn for chiming in after all this time! I've since figured this out, but forgot I posted here about it.

I have a custom rb file that I reference when I run sass via the command line - like so:

sass --update sass:css -r file_mod.rb

in file_mod.rb, I have the following ruby function which does the trick:

require 'sass'

module GETMODINT
def file_url(staticFilePath,staticHost,filePath)
assert_type filePath, :String
filePath = filePath.value #get string value of literal
staticFilePath = staticFilePath.value
staticHost = staticHost.value
modtime = File.mtime(filePath).to_i
#Sass::Script::Number.new(modtime)

fileBaseName = File.basename filePath, '.*'
fileDir = File.dirname(filePath).sub(staticFilePath,'')
fileExt = File.extname(filePath)
path = "url('#{staticHost}#{fileDir}/#{fileBaseName}.#{modtime}#{fileExt}')"
return Sass::Script::String.new(path)
end
Sass::Script::Functions.declare :modInt, [:filePath]
end

module Sass::Script::Functions
include GETMODINT
end

Then, in a sass mixin, I simply reference the file_url function, passing it the parameters it needs to build the result:

@mixin backgroundImage($path, $position:0 0, $repeat:no-repeat) {
background: {
image:file_url($staticFilePath,$staticHost,$path);
position:$position;
repeat:$repeat;
}
}

In my case, I'm using it to construct a css background image path. Should be easily modified to suit other purposes.

How to remove the hash from Compass's generated sprite image filenames?

Unfortunately asset_cache_buster :none option does not disable adding the hash to the end of the filename.

Like I wrote few time ago (in french), Compass has no way to disable the cache hash buster, but I propose a solution.

In your configuration file (eg config.rb) add the following lines:

# Make a copy of sprites with a name that has no uniqueness of the hash.
on_sprite_saved do |filename|
if File.exists?(filename)
FileUtils.cp filename, filename.gsub(%r{-s[a-z0-9]{10}\.png$}, '.png')
end
end

# Replace in stylesheets generated references to sprites
# by their counterparts without the hash uniqueness.
on_stylesheet_saved do |filename|
if File.exists?(filename)
css = File.read filename
File.open(filename, 'w+') do |f|
f << css.gsub(%r{-s[a-z0-9]{10}\.png}, '.png')
end
end
end

Now, uses compass cleanto remove generated files and restarts a compilation with compass compile.

You obtain, for example, a images/icons-scb1e5456d5.png file and a images/icons.png file. In the stylesheets, all references to the sprites now point to the version without hash.

Be sure to keep the file has a hash provided to optimize compile times by Compass.

Compass - CSS files caching

As detailed by Scott Davis (Compass core team dev), in this Compass Github Issue (opened by myself) :

It's not a cache buster in the sense of the web it's a uniqueness hash. It's how compass tracks changes to the sprite file so that we know if it needs to be recompiled

So the answer is no, as Compass does not support cache busting.

How to remove the hash from Compass's generated sprite image filenames?

Unfortunately asset_cache_buster :none option does not disable adding the hash to the end of the filename.

Like I wrote few time ago (in french), Compass has no way to disable the cache hash buster, but I propose a solution.

In your configuration file (eg config.rb) add the following lines:

# Make a copy of sprites with a name that has no uniqueness of the hash.
on_sprite_saved do |filename|
if File.exists?(filename)
FileUtils.cp filename, filename.gsub(%r{-s[a-z0-9]{10}\.png$}, '.png')
end
end

# Replace in stylesheets generated references to sprites
# by their counterparts without the hash uniqueness.
on_stylesheet_saved do |filename|
if File.exists?(filename)
css = File.read filename
File.open(filename, 'w+') do |f|
f << css.gsub(%r{-s[a-z0-9]{10}\.png}, '.png')
end
end
end

Now, uses compass cleanto remove generated files and restarts a compilation with compass compile.

You obtain, for example, a images/icons-scb1e5456d5.png file and a images/icons.png file. In the stylesheets, all references to the sprites now point to the version without hash.

Be sure to keep the file has a hash provided to optimize compile times by Compass.

Hard cache busting of assets w/ Compass

Compass already adds a hash as a cache buster in the generated sprite sheets (eg icons-sf6a3361a01.png).

For other images, you can use the following code in your config.rb, which is found in the documentation:

asset_cache_buster do |path, real_path|
if File.exists?(real_path)
pathname = Pathname.new(path)
modified_time = File.mtime(real_path).strftime("%s")
new_path = "%s/%s-%s%s" % [pathname.dirname, pathname.basename(pathname.extname), modified_time, pathname.extname]

{:path => new_path, :query => nil}
end
end

Thus, the SCSS code

.icon-cloud {
background: image-url("weather-cloud.png") no-repeat 0 0;
}

generates an image with an embedded cache buster (weather-cloud-1365271586.png):

.icon-cloud {
background: url('../img/weather-cloud-1365271586.png') no-repeat 0 0;
}

Warning: Compass doesn't duplicate or rename the image. You'll have to create a rewrite rule that will allow your web server to serve the good image.



Related Topics



Leave a reply



Submit