Class: Vitrine::AssetCompiler

Inherits:
Sinatra::Base
  • Object
show all
Defined in:
lib/asset_compiler.rb

Overview

The part of Vitrine responsible for SASS and CoffeeScript compilation and caching. By default it will assume your public directory is set on the inner app in the Rack stack, and can be retreived using the standard Sinatra settings protocol, like so:

@app.settings.public_folder

However, you can also set this setting on the app object using the AssetCompiler#public_dir accessor.

use Vitrine::AssetCompiler do | compiler |
  compiler.public_dir = File.dirname(__FILE__) + '/public'
end

This allows you to use the asset compiler when the inner app is not a Sinatra application.

Obviously, the usual limitation apply for this kind of workflow - you pretty much have to have an ExecJS env on yourserver, or else…

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#public_dirObject

An explicit override for public_folder setting, if set will take precedence over the setting



27
28
29
# File 'lib/asset_compiler.rb', line 27

def public_dir
  @public_dir
end

Instance Method Details

#cache_bust!Object



112
113
114
115
116
# File 'lib/asset_compiler.rb', line 112

def cache_bust!
  response.headers['Cache-Control'] = 'private'
  response.headers['Pragma'] = 'no-cache'
  response.headers.delete('ETag')
end

#forward_or_halt(msg) ⇒ Object



145
146
147
148
149
150
151
152
# File 'lib/asset_compiler.rb', line 145

def forward_or_halt(msg)
  if @app
    log "Forwarding, #{msg} -> pub #{get_public.inspect}"
    forward 
  else
    halt 404, msg
  end
end

#get_publicObject

Get path to the public directory, trying (in order:) self.public_dir reader the inner app’s public_folder setting my own public_folder setting



135
136
137
138
139
140
141
142
143
# File 'lib/asset_compiler.rb', line 135

def get_public
  inner_public = if @app && @app.respond_to?(:settings)
    @app.settings.public_folder
  else
    nil
  end
  choices = [@public_dir, inner_public, settings.public_dir]
  choices.compact.shift
end

#log(msg) ⇒ Object



154
155
156
# File 'lib/asset_compiler.rb', line 154

def log(msg)
  env['captivity.logger'].debug(msg) if env['captivity.logger']
end

#mtime_cache(path) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/asset_compiler.rb', line 118

def mtime_cache(path)
  # Mix in the request URL into the cache key so that we can hash
  # .map sourcemaps and .js compiles based off of the same file path
  # and mtime
  key = [File.expand_path(path), File.mtime(path), request.path_info, get_public]
  cache_sha = Digest::SHA1.hexdigest(Marshal.dump(key))
  
  etag cache_sha
  cache_control :public, :must_revalidate
  
  log "---> Vitrine AC: Recompiling #{path} -> #{request.path_info}"
end


158
159
160
161
162
163
164
# File 'lib/asset_compiler.rb', line 158

def print_compilation_error(e)
  # Print the error to $stderr for good measure
  $stderr.puts "Error when building asset #{request.url.inspect}: #{e.class}: #{e.message}"
  e.backtrace.each do | line |
    $stderr.puts "\t#{line}"
  end
end