Your assets are covered. See README.rdoc for more.
Methods
public class
Constants
VERSION | = | self.version | This gem’s version number. | |
TYPES | = | [:css, :js] | Types of supported assets; currently [:css, :js]. | |
ASSETS_DIR | = | defined?(Rails.public_path) && Rails.public_path.present? ? Rails.public_path : 'public' | Base directory in which all assets are kept, e.g., ‘public/’. | |
STYLESHEETS_PATH | = | '/stylesheets' | Root URL path for all stylesheets. For public-facing use. | |
JAVASCRIPTS_PATH | = | '/javascripts' | Root URL path for all JavaScripts. For public-facing use. | |
STYLESHEETS_DIR | = | File.join(ASSETS_DIR, 'stylesheets') | Directory in which all stylesheets are kept, e.g., ‘public/stylesheets’. For internal filesystem use. | |
JAVASCRIPTS_DIR | = | File.join(ASSETS_DIR, 'javascripts') | Directory in which all JavaScripts are kept, e.g., ‘public/javascripts’. For internal filesystem use. | |
RELATIVE_CONFIG_FILEPATH | = | File.join('config', 'assets.yml') | Relative path for the config file. | |
CONFIG_FILEPATH | = | File.join(RAILS_ROOT, RELATIVE_CONFIG_FILEPATH) | Absolute path for the config file. |
Public class methods
Returns true if the specified asset exists in the file system:
AssetHat.asset_exists?('application.css', :css) # => true if public/stylesheets/application.css exists AssetHat.asset_exists?('some-plugin.js', :js) # => true if public/javascripts/some-plugin.js exists
See also AssetHat.assets_dir.
# File lib/asset_hat.rb, line 154 154: def self.asset_exists?(filename, type) 155: # Process arguments 156: type = type.to_sym 157: unless TYPES.include?(type) 158: raise %{Unknown type "#{type}"; should be one of: #{TYPES.join(', ')}.} 159: return 160: end 161: 162: # Default to `{:css => {}, :js => {}}` 163: @asset_exists ||= TYPES.inject({}) { |hsh, t| hsh.merge(t => {}) } 164: 165: if @asset_exists[type][filename].nil? 166: @asset_exists[type][filename] = 167: File.exist?(File.join(self.assets_dir(type), filename)) 168: end 169: @asset_exists[type][filename] 170: end
Returns the relative path to the directory where the original CSS or JS files are stored. For internal filesystem use.
type argument: :css or :js
# File lib/asset_hat.rb, line 63 63: def self.assets_dir(type) 64: case type.to_sym 65: when :css ; STYLESHEETS_DIR 66: when :js ; JAVASCRIPTS_DIR 67: else 68: raise %{Unknown type "#{type}"; should be one of: #{TYPES.join(', ')}.} 69: nil 70: end 71: end
Returns the root URL path where the original CSS or JS files are stored. For external URL-building use.
type argument: :css or :js
# File lib/asset_hat.rb, line 77 77: def self.assets_path(type) 78: case type.to_sym 79: when :css ; STYLESHEETS_PATH 80: when :js ; JAVASCRIPTS_PATH 81: else 82: raise %{Unknown type "#{type}"; should be one of: #{TYPES.join(', ')}.} 83: nil 84: end 85: end
Returns the extension-less names of files in the given bundle:
AssetHat.bundle_filenames('application', :css) # => ['reset', 'application'] AssetHat.bundle_filenames('non-existent-file', :css) # => nil
# File lib/asset_hat.rb, line 210 210: def self.bundle_filenames(bundle, type) 211: # Process arguments 212: unless TYPES.include?(type.to_sym) 213: raise %{Unknown type "#{type}"; should be one of: #{TYPES.join(', ')}.} 214: return 215: end 216: 217: self.config[type.to_s]['bundles'][bundle.to_s] rescue nil 218: end
Returns the full paths of files in the given bundle:
AssetHat.bundle_filenames('application', :css) # => ['/path/to/app/public/stylesheets/reset.css', '/path/to/app/public/stylesheets/application.css'] AssetHat.bundle_filenames('non-existent-file', :css) # => nil
# File lib/asset_hat.rb, line 227 227: def self.bundle_filepaths(bundle, type) 228: # Process arguments 229: unless TYPES.include?(type.to_sym) 230: raise %{Unknown type "#{type}"; should be one of: #{TYPES.join(', ')}.} 231: return 232: end 233: 234: dir = self.assets_dir(type) 235: filenames = self.bundle_filenames(bundle, type) 236: filepaths = filenames.present? ? 237: filenames.map { |fn| File.join(dir, "#{fn}.#{type}") } : nil 238: end
Returns the relative path to the directory where CSS or JS bundles are stored. For internal filesystem use.
Usage:
AssetHat.bundles_dir # => 'bundles' AssetHat.bundles_dir(:ssl => true) # => 'bundles/ssl' AssetHat.bundles_dir(:css) # => 'public/stylesheets/bundles' AssetHat.bundles_dir(:js, :ssl => true) # => 'public/javascripts/bundles/ssl
Options:
- ssl
- Set this to true if the stylesheet references images via SSL. Defaults to false.
# File lib/asset_hat.rb, line 105 105: def self.bundles_dir(*args) 106: options = args.extract_options! 107: options.symbolize_keys!.reverse_merge!(:ssl => false) 108: type = args.first 109: 110: dir = type.present? ? File.join(assets_dir(type), 'bundles') : 'bundles' 111: dir = File.join(dir, 'ssl') if options[:ssl] 112: dir 113: end
Returns the root URL path where CSS or JS bundles are stored. For external URL-building use.
Usage:
AssetHat.bundles_path(:css) # => 'public/stylesheets/bundles' AssetHat.bundles_path(:js, :ssl => true) # => 'public/javascripts/bundles/ssl
Options:
- ssl
- Set this to true if the stylesheet references images via SSL. Defaults to false.
# File lib/asset_hat.rb, line 129 129: def self.bundles_path(type, options={}) 130: type = type.to_sym 131: unless TYPES.include?(type) 132: raise %{Unknown type "#{type}"; should be one of: #{TYPES.join(', ')}.} 133: return 134: end 135: 136: path = case type 137: when :css ; STYLESHEETS_PATH 138: when :js ; JAVASCRIPTS_PATH 139: else nil 140: end 141: path += '/bundles' 142: path += '/ssl' if options[:ssl] 143: path 144: end
Returns true if bundles should be included as single minified files (e.g., in production), or false if bundles should be included as separate, unminified files (e.g., in development). To modify this value, set config.action_controller.perform_caching (boolean) in your environment.
# File lib/asset_hat.rb, line 178 178: def self.cache? ; ActionController::Base.perform_caching ; end
Precomputes and caches the last commit ID for all bundles. Your web server process(es) should run this at boot to avoid overhead during user runtime.
# File lib/asset_hat/vcs.rb, line 75 75: def self.cache_last_commit_ids 76: AssetHat::TYPES.each do |type| 77: next if AssetHat.config[type.to_s].blank? || 78: AssetHat.config[type.to_s]['bundles'].blank? 79: 80: AssetHat.config[type.to_s]['bundles'].keys.each do |bundle| 81: # Memoize commit ID for this bundle 82: AssetHat.last_bundle_commit_id(bundle, type) if AssetHat.cache? 83: 84: # Memoize commit IDs for each file in this bundle 85: AssetHat.bundle_filepaths(bundle, type).each do |filepath| 86: AssetHat.last_commit_id(filepath) 87: end 88: end 89: end 90: end
# File lib/asset_hat.rb, line 294 294: def self.clear_html_cache 295: html_cache = {} 296: end
Reads ActionController::Base.asset_host, which can be a String or Proc, and returns a String. Should behave just like Rails 2.3.x’s private `compute_asset_host` method, but with a simulated request.
Example environment config for CDN support via SSL:
# In config/environments/production.rb: config.action_controller.asset_host = Proc.new do |source, request| "#{request.protocol}cdn#{source.hash % 4}.example.com" # => 'http://cdn0.example.com', 'https://cdn1.example.com', etc. end
If your CDN doesn’t have SSL support, you can instead revert SSL pages to serving assets from your web server:
config.action_controller.asset_host = Proc.new do |source, request| request.ssl? ? nil : "http://cdn#{source.hash % 4}.example.com" end
Options:
- ssl
- Set to true to simulate a request via SSL. Defaults to false.
# File lib/asset_hat.rb, line 263 263: def self.compute_asset_host(asset_host, source, options={}) 264: host = asset_host 265: if host.is_a?(Proc) || host.respond_to?(:call) 266: case host.is_a?(Proc) ? 267: host.arity : host.method(:call).arity 268: when 2 269: if defined?(ActionDispatch) 270: request_class = ActionDispatch::Request 271: else # Rails 2.x 272: request_class = ActionController::Request 273: end 274: request = request_class.new( 275: 'HTTPS' => options[:ssl] ? 'on' : 'off') 276: host = host.call(source, request) 277: else 278: host = host.call(source) 279: end 280: else 281: host %= (source.hash % 4) if host =~ /%d/ 282: end 283: host 284: end
Nested-hash version of config/assets.yml.
# File lib/asset_hat.rb, line 47 47: def self.config 48: unless File.exists?(CONFIG_FILEPATH) 49: raise '`config/assets.yml` is missing! ' + 50: 'Run `rake asset_hat:config` to generate it.' and return 51: end 52: 53: if !cache? || @config.blank? 54: @config = YAML.load(ERB.new(File.read(CONFIG_FILEPATH)).result) 55: end 56: @config 57: end
Returns the value of Rails.application.config.consider_all_requests_local or its equivalent in older versions of Rails. To modify this value, set config.consider_all_requests_local (boolean) in your environment.
# File lib/asset_hat.rb, line 185 185: def self.consider_all_requests_local? 186: if defined?(Rails) && Rails.respond_to?(:application) 187: Rails.application.config.consider_all_requests_local 188: else # Rails 2.x 189: ActionController::Base.consider_all_requests_local 190: end 191: end
Usage:
AssetHat.last_bundle_commit_id('application', :css)
Returns a string of the latest commit ID for the given bundle, based on which of its files were most recently modified in the repository. If no ID can be found, `nil` is returned.
# File lib/asset_hat/vcs.rb, line 45 45: def self.last_bundle_commit_id(bundle, type) 46: # Process arguments 47: type = type.to_sym 48: unless TYPES.include?(type) 49: raise %{Unknown type "#{type}"; should be one of: #{TYPES.join(', ')}.} 50: return 51: end 52: 53: # Default to `{:css => {}, :js => {}}` 54: @last_bundle_commit_ids ||= 55: TYPES.inject({}) { |hsh, t| hsh.merge(t => {}) } 56: 57: if @last_bundle_commit_ids[type][bundle].blank? 58: dir = self.assets_dir(type) 59: filepaths = self.bundle_filepaths(bundle, type) 60: if filepaths.present? 61: @last_bundle_commit_ids[type][bundle] = 62: self.last_commit_id(*filepaths) 63: end 64: end 65: 66: @last_bundle_commit_ids[type][bundle] 67: end
Usage:
AssetHat.last_commit_id('public/stylesheets/application.css') AssetHat.last_commit_id('public/stylesheets/ie.css', 'public/stylesheets/ie7.css', 'public/stylesheets/ie6.css')
Returns a string of the commit ID for the file with the most recent commit. If the file(s) cannot be found, `nil` is returned. Options:
- vcs
- Version control system. Currently, the only supported value is :git.
# File lib/asset_hat/vcs.rb, line 18 18: def self.last_commit_id(*args) 19: # Process arguments 20: options = args.extract_options! 21: options = options.symbolize_keys.reverse_merge(:vcs => :git) 22: filepaths = args.join(' ') 23: 24: # Validate options 25: if options[:vcs] != :git 26: raise 'Git is currently the only supported VCS.' and return 27: end 28: 29: @last_commit_ids ||= {} 30: if @last_commit_ids[filepaths].blank? 31: h = `git log -1 --pretty=format:%h #{filepaths} 2>/dev/null` 32: # `h` has either the abbreviated Git commit hash or an empty string 33: @last_commit_ids[filepaths] = h if h.present? 34: end 35: @last_commit_ids[filepaths] 36: end
Returns the expected path for the minified version of an asset:
AssetHat.min_filepath('public/stylesheets/bundles/application.css', 'css') # => 'public/stylesheets/bundles/application.min.css'
See also AssetHat::CSS.min_filepath and AssetHat::JS.min_filepath.
# File lib/asset_hat.rb, line 200 200: def self.min_filepath(filepath, extension) 201: filepath.sub(/([^\.]*).#{extension}$/, "\\1.min.#{extension}") 202: end
Returns true if the asset host differs between SSL and non-SSL pages, or false if the asset host doesn’t change.
# File lib/asset_hat.rb, line 288 288: def self.ssl_asset_host_differs? 289: asset_host = ActionController::Base.asset_host 290: AssetHat.compute_asset_host(asset_host, 'x.png') != 291: AssetHat.compute_asset_host(asset_host, 'x.png', :ssl => true) 292: end
Returns this gem’s version number. See also VERSION.
# File lib/asset_hat/version.rb, line 3 3: def self.version 4: data_filepath = File.join(File.dirname(__FILE__), %w[.. .. VERSION.yml]) 5: data = YAML.load(File.open(data_filepath, 'r')) 6: [:major, :minor, :patch, :build]. 7: map { |x| data[x] }.reject(&:blank?).join('.') 8: end