Where’s Your Assets?

Damn! I’m hard coding all the project imagery assets within my stylesheets. What if the URL to those image assets change? This is where Compass will come to the rescue.

To be completely frank, I almost completed an entire bowel movement upon discovery of this sneaky little helper I’m going to discuss. The story goes like this; work locally with your assets folder, upload your code and assets to the deployment server, test, and then finally make it production ready, but we’re missing one important aspect from this entire process; What happens if the location of those assets change –or– worse they’re moved to a CDN? Now you’ve gotta sift through hundreds, or even thousands of lines of code and swap out the URLs. Have no fear though as we can solve this problem in a non–trivial manner using a special compass helper called image-url.

Before I found the image-url helper I was doing the following…

$assets_path: "http://example.com";
background: url(#{$assets_path}/img/logo-sprite.png) -277px 0 no-repeat;

Figure 1

Executing the method in Figure 1, I only had to change the $assets_path and call it a day, but that’s not good enough yet. Compass can do way better than my silly Sass variable. This approach only works if your images always rest within an img directory, but it’s flawed for that very reason.

Lets take a look at the following examples to get a better understanding of this mysterious beast called image-url.

Compass’ config.rb

# Require any additional compass plugins? Uncomment the following line
# require "/Library/Ruby/Gems/1.8/gems/compass-X.XX.X/lib/compass-plugin-name.rb";

# Set this to the root of your project when deployed:
http_path = "/"

# Set the images directory relative to your http_path or change
# the location of the images themselves using http_images_path:
# http_images_dir = "assets/images"

# Production Assets URL
http_images_path = "http://your-url-goes-here/img"

# Compass will automatically add cache busters to your images based on image timestamps. 
# This will keep browser caches from displaying the wrong image if you change the image but not the url. 
# If you don’t want this behavior, it's easy to configure or disable:
# UNCOMMENT THE NEXT THREE LINES
#asset_cache_buster do |http_path, real_path|
#  nil
#end

# Project Assets Location
css_dir = "/"
sass_dir = "scss"
images_dir = "img"
javascripts_dir = "js"

# Development
output_style = :expanded
environment = :development

# Production
# output_style = :compressed
# environment = :production

# To enable relative paths to assets via compass helper functions Uncomment the following line:
# relative_assets = true

line_comments = false
color_output = false

# If you prefer the indented syntax, you might want to regenerate this
# project again passing --syntax sass, or you can uncomment this:
# preferred_syntax = :sass
# and then run:
# sass-convert -R --from scss --to sass scss scss && rm -rf sass && mv scss sass

Figure 2

Using our config.rb example above we’re including two very important helpers http_images_path & relative_assets. Setting the value for http_images_path will direct all your image assets to your production server, CDN or any other dark closet you’re hiding things in. It can also generate cache–busting query strings based on image timestamps. This will keep browser caches from displaying the wrong image if you change the image but not the url. If you don’t want this behavior, it’s easy to configure or disable (see lines 14 thru 20 from Figure 2).

Say I want to keep my images on a sub–domain, then all I would do is change the path like so…

http_images_path = "http://static.mysite/img/"

Figure 3

and then in our .scss file…

// bring compass into our project
@import "compass";

// image-url() example.
// Compass will automatically generate a relative URL to the file.
background: image-url("logo-sprite.png") -277px 0 no-repeat;

Figure 4

This will direct all my assets to the URL I’ve defined for http_images_path…Hot Damn! that’s some sweet sauce. I could take this one step further and uncomment the relative_assets line while working locally like so;

# Production Assets URL
http_images_path = "http://your-url-goes-here/img"

# To enable relative paths to assets via compass helper functions uncomment the following line:
relative_assets = true

Figure 5

relative_assets will now serve all the assets from your local assets/images directory that’s defined by your config.rb file seen in Figure 6 Line 4 below:

# Project Assets Location
css_dir = "/"
sass_dir = "scss"
images_dir = "img"
javascripts_dir = "js"

Figure 6

Pretty rad huh? we can also use relative URLs based on our http_path

# Set this to the root of your project when deployed:
http_path = "http://your-url-goes-here.com/path-to-your-directory/"

# Set the images directory relative to your http_path or change
# the location of the images themselves using http_images_path:
http_images_dir = "img"

# Production Assets URL
# http_images_path = "http://your-url-goes-here/img"

# Project Assets Location
css_dir = "/"
sass_dir = "scss"
# images_dir = "img"
javascripts_dir = "js"

# To enable relative paths to assets via compass helper functions Uncomment the following line:
# relative_assets = true

Figure 7

Although this method works just fine I prefer to use http_images_path and call it a day. As always, hit me up with any questions, comments, suggestions or rants. Now go and make wonderful relative URLs frustration free on your next project.

You’re links Madam