Class: Juicer::CssCacheBuster

Inherits:
Object
  • Object
show all
Includes:
Chainable
Defined in:
lib/juicer/css_cache_buster.rb

Overview

The CssCacheBuster is a tool that can parse a CSS file and substitute all referenced URLs by a URL appended with a timestamp denoting it's last change. This causes the URLs to be unique every time they've been modified, thus facilitating using a far future expires header on your web server.

See Juicer::CacheBuster for more information on how the cache buster URLs work.

When dealing with CSS files that reference absolute URLs like /images/1.png you must specify the :document_root option that these URLs should be resolved against.

When dealing with full URLs (ie including hosts) you can optionally specify an array of hosts to recognize as “local”, meaning they serve assets from the :document_root directory. This way even asset host cycling can benefit from cache busters.

Instance Method Summary collapse

Methods included from Chainable

included, #next_in_chain, #next_in_chain=

Constructor Details

#initialize(options = {}) ⇒ CssCacheBuster

Returns a new instance of CssCacheBuster.


27
28
29
30
31
32
33
# File 'lib/juicer/css_cache_buster.rb', line 27

def initialize(options = {})
  @document_root = options[:document_root]
  @document_root.sub!(%r{/?$}, "") if @document_root
  @type = options[:type] || :soft
  @hosts = (options[:hosts] || []).collect { |h| h.sub!(%r{/?$}, "") }
  @contents = @base = nil
end

Instance Method Details

#save(file, output = nil) ⇒ Object

Update file. If no output is provided, the input file is overwritten


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/juicer/css_cache_buster.rb', line 38

def save(file, output = nil)
  @contents = File.read(file)
  self.base = File.dirname(file)
  used = []

  urls(file).each do |asset|
    begin
      next if used.include?(asset.path)
      @contents.gsub!(asset.path, asset.path(:cache_buster_type => @type))
      used.push(asset.path)
    rescue Errno::ENOENT
      puts "Unable to locate file #{asset.path}, skipping cache buster"
    rescue ArgumentError => e
      if e.message =~ /No document root/
        puts "Unable to resolve path #{asset.path} without :document_root option"
      else
        puts "Unable to locate #{asset.path}, skipping cache buster"
      end
    end
  end

  File.open(output || file, "w") { |f| f.puts @contents }
  @contents = nil
end

#urls(file) ⇒ Object

Returns all referenced URLs in file. Returned paths are absolute (ie, they're resolved relative to the file path.


69
70
71
72
73
74
75
# File 'lib/juicer/css_cache_buster.rb', line 69

def urls(file)
  @contents = File.read(file) unless @contents

  @contents.scan(/url\([\s"']*([^\)"'\s]*)[\s"']*\)/m).collect do |match|
    path_resolver.resolve(match.first)
  end
end