class Sinatra::AssetPack::Options

Assets.

Common usage

SinatraApp.assets {
  # dsl stuff here
}

a = SinatraApp.assets

Getting options:

a.js_compression
a.output_path

Served:

a.served         # { '/js' => '/var/www/project/app/js', ... }
                 # (URL path => local path)

Packages:

a.packages       # { 'app.css' => #<Package>, ... }
                 # (name.type => package instance)

Build:

a.build! { |path| puts "Building #{path}" }
a.build_packages! { |path| puts "Building package #{path}" }
a.build_files! { |path| puts "Building files #{path}" }

Lookup:

a.local_path_for('/images/bg.gif')
a.served?('/images/bg.gif')

a.glob(['/js/*.js', '/js/vendor/**/*.js'])
# Returns a HashArray of (local => remote)

Attributes

app[R]
packages[R]
served[R]

Stuff

Public Class Methods

new(app) { |self| ... } click to toggle source
# File lib/sinatra/assetpack/options.rb, line 46
def initialize(app, &blk)
  unless app.root?
    raise Error, "Please set :root in your Sinatra app."
  end

  @app             = app
  @js_compression  = :jsmin
  @css_compression = :simple
  @reload_files_cache = true

  begin
    @output_path   = app.public
  rescue NoMethodError
    @output_path   = app.public_folder
  end

  @js_compression_options  = Hash.new
  @css_compression_options = Hash.new
  @dynamic_asset_cache     = Hash.new

  @ignored = Array.new

  reset!

  # Defaults!
  serve '/css',    :from => 'app/css'     rescue Errno::ENOTDIR
  serve '/js',     :from => 'app/js'      rescue Errno::ENOTDIR
  serve '/images', :from => 'app/images'  rescue Errno::ENOTDIR

  ignore '.*'
  ignore '_*'

  blk.arity <= 0 ? instance_eval(&blk) : yield(self)  if block_given?
end

Public Instance Methods

cache!() { |path| ... } click to toggle source

Caches the packages.

# File lib/sinatra/assetpack/options.rb, line 204
def cache!(&blk)
  return if app.reload_templates

  session = Rack::Test::Session.new app
  packages.each { |_, pack|
    yield pack.path if block_given?
    session.get(pack.path)
  }
end
clear_ignores!() click to toggle source

Makes nothing ignored. Use this if you don’t want to ignore dotfiles and underscore files.

# File lib/sinatra/assetpack/options.rb, line 118
def clear_ignores!
  @ignored  = Array.new
end
css(name, *args) click to toggle source

Adds some CSS packages.

css :app, [ '/css/screen.css', ... ]
css :app, '/css/app.css', [ '/css/screen.css', ... ]
# File lib/sinatra/assetpack/options.rb, line 141
def css(name, *args) #path, files=[])
  js_or_css :css, name, *args
end
css_compression(name=nil, options=nil) click to toggle source
# File lib/sinatra/assetpack/options.rb, line 192
def css_compression(name=nil, options=nil)
  @css_compression = name unless name.nil?
  @css_compression_options = options if options.is_a?(Hash)
  @css_compression
end
dyn_local_file_for(request, from) click to toggle source

Returns the local file for a given URI path. (for dynamic files) Returns nil if a file is not found.

# File lib/sinatra/assetpack/options.rb, line 234
def dyn_local_file_for(request, from)
  file = request.dup
  extension = File.extname(request)
  # Remove extension
  file.gsub!(/#{extension}$/, "")
  # Remove cache-buster (/js/app.28389 => /js/app)
  file.gsub!(/\.[a-f0-9]{32}$/, "")

  matches = Dir[File.join(expand_from(from), "#{file}.*")]

  # Fix for filenames with dots (can't do this with glob)
  matches = matches.select { |f| f =~ /#{file}\.[^.]+$/ }

  # Sort static file match, weighting exact file extension matches
  # first, then registered Tilt formats
  matches.sort! do |candidate, _|
    cfmt = File.extname(candidate)[1..-1]
    efmt = extension[1..-1]
    (cfmt == efmt or AssetPack.tilt_formats[cfmt] == efmt) ? -1 : 1
  end
  matches.first
end
expires(*args) click to toggle source
# File lib/sinatra/assetpack/options.rb, line 178
def expires(*args)
  if args.empty?
    @expires
  else
    @expires = args
  end
end
fetch_dynamic_asset(path) { || ... } click to toggle source

Fetches the contents of a dynamic asset. If ‘cache_dynamic_assets` is set, check file mtime and potentially return contents from cache instead of re-compiling. Yields to a block to compile & render the asset.

# File lib/sinatra/assetpack/options.rb, line 301
def fetch_dynamic_asset(path)
  return yield unless cache_dynamic_assets

  mtime = File.mtime(path)
  cached_mtime, contents = @dynamic_asset_cache[path]

  if cached_mtime.nil? || mtime != cached_mtime
    @dynamic_asset_cache[path] = [mtime, yield]
    @dynamic_asset_cache[path][1]
  else
    contents
  end
end
files(match=nil) click to toggle source

Returns the files as a hash.

# File lib/sinatra/assetpack/options.rb, line 258
def files(match=nil)
  return @files unless @reload_files_cache

  # All
  # A buncha tuples
  tuples = @served.map { |prefix, local_path|
    path = File.expand_path(File.join(@app.root, local_path))
    spec = File.join(path, '**', '*')

    Dir[spec].map { |f|
      [ to_uri(f, prefix, path), f ]  unless File.directory?(f)
    }
  }.flatten.compact

  @reload_files_cache = false
  @files = Hash[*tuples]
end
glob(match) click to toggle source

Returns an array of URI paths of those matching given globs.

glob('spec')
glob(['spec1', 'spec2' ...])
# File lib/sinatra/assetpack/options.rb, line 281
def glob(match)
  paths = Array.new(match) # Force array-ness

  paths.map! do |spec|
    if spec.include?('*')
      files.select do |file, _|
        # Dir#glob like source matching
        File.fnmatch?(spec, file, File::FNM_PATHNAME | File::FNM_DOTMATCH)
      end.sort
    else
      [spec, files[spec]]
    end
  end

  Hash[*paths.flatten]
end
ignore(spec) click to toggle source

Ignores a given path spec.

# File lib/sinatra/assetpack/options.rb, line 107
def ignore(spec)
  if spec[0] == '/'
    @ignored << "#{spec}"
    @ignored << "#{spec}/**"
  else
    @ignored << "**/#{spec}"
    @ignored << "**/#{spec}/**"
  end
end
ignored?(fn) click to toggle source

Checks if a given path is ignored.

# File lib/sinatra/assetpack/options.rb, line 123
def ignored?(fn)
  @ignored.any? { |spec| File.fnmatch spec, fn }
end
js(name, *args) click to toggle source

Adds some JS packages.

js :foo, [ '/js/vendor/jquery.*.js', ... ]
js :foo, '/js/foo.js', [ '/js/vendor/jquery.*.js', ... ]
# File lib/sinatra/assetpack/options.rb, line 132
def js(name, *args)
  js_or_css :js, name, *args
end
js_compression(name=nil, options=nil) click to toggle source
# File lib/sinatra/assetpack/options.rb, line 186
def js_compression(name=nil, options=nil)
  @js_compression = name unless name.nil?
  @js_compression_options = options if options.is_a?(Hash)
  @js_compression
end
js_or_css(type, name, *args) click to toggle source
# File lib/sinatra/assetpack/options.rb, line 145
def js_or_css(type, name, *args)
  # Account for "css :name, '/path/to/css', [ files ]"
  if args[0].is_a?(String) && args[1].respond_to?(:each)
    path, files = args

  # Account for "css :name, [ files ]"
  elsif args[0].respond_to?(:each)
    path  = "/assets/#{name}.#{type}" # /assets/foobar.css by default
    files = args[0]

  else
    raise ArgumentError
  end

  @packages["#{name}.#{type}"] = Package.new(self, name, type, path, files)
end
local_file_for(request) click to toggle source

Returns the local file for a given URI path. Returns nil if a file is not found.

# File lib/sinatra/assetpack/options.rb, line 220
def local_file_for(request)
  request = request.squeeze('/')
  serve_path, from = served.detect { |path, _| request.start_with?(path) }

  return if !from

  path = File.join(expand_from(from), request.sub(serve_path, ''))
  return if !File.file?(path)

  path
end
reset!() click to toggle source

Undo defaults.

# File lib/sinatra/assetpack/options.rb, line 100
def reset!
  @served   = Hash.new
  @packages = Hash.new
  @reload_files_cache = true
end
serve(path, options={}) click to toggle source

DSL methods

# File lib/sinatra/assetpack/options.rb, line 84
def serve(path, options={})
  unless from = options[:from]
    raise ArgumentError, "Parameter :from is required" 
  end

  expanded = expand_from(from)

  unless File.directory? expanded
    raise Errno::ENOTDIR, expanded
  end

  @served[path] = from
  @reload_files_cache = true
end
served?(path) click to toggle source
# File lib/sinatra/assetpack/options.rb, line 214
def served?(path)
  !! local_file_for(path)
end

Private Instance Methods

expand_from(from) click to toggle source
# File lib/sinatra/assetpack/options.rb, line 332
def expand_from(from)
  if from.start_with?('/')
    from
  else
    File.join(app.root, from)
  end
end
to_uri(f, prefix, path) click to toggle source

Returns a URI for a given file

path = '/projects/x/app/css'
to_uri('/projects/x/app/css/file.sass', '/styles', path) => '/styles/file.css'
# File lib/sinatra/assetpack/options.rb, line 320
def to_uri(f, prefix, path)
  fn = (prefix + f.gsub(path, '')).squeeze('/')

  # Switch the extension ('x.sass' => 'x.css')
  file_ext = File.extname(fn).to_s[1..-1]
  out_ext  = AssetPack.tilt_formats[file_ext]

  fn = fn.gsub(/\.#{file_ext}$/, ".#{out_ext}")  if file_ext && out_ext

  fn
end