class Middleman::Extensions::AssetHash::Middleware

The asset hash middleware is responsible for rewriting references to assets to include their new, hashed name.

Public Class Methods

new(app, options={}) click to toggle source
# File lib/middleman-more/extensions/asset_hash.rb, line 62
def initialize(app, options={})
  @rack_app        = app
  @exts            = options[:exts]
  @ignore          = options[:ignore]
  @exts_regex_text = @exts.map { |e| Regexp.escape(e) }.join('|')
  @middleman_app   = options[:middleman_app]
end

Public Instance Methods

call(env) click to toggle source
# File lib/middleman-more/extensions/asset_hash.rb, line 70
def call(env)
  status, headers, response = @rack_app.call(env)

  # We don't want to use this middleware when rendering files to figure out their hash!
  return [status, headers, response] if env['bypass_asset_hash'] == 'true'

  path = ::Middleman::Util.full_path(env['PATH_INFO'], @middleman_app)

  if path =~ /(^\/$)|(\.(htm|html|php|css|js)$)/
    body = ::Middleman::Util.extract_response_text(response)
    if body
      status, headers, response = Rack::Response.new(rewrite_paths(body, path), status, headers).finish
    end
  end

  [status, headers, response]
end

Private Instance Methods

rewrite_paths(body, path) click to toggle source
# File lib/middleman-more/extensions/asset_hash.rb, line 90
def rewrite_paths(body, path)
  dirpath = Pathname.new(File.dirname(path))

  # TODO: This regex will change some paths in plan HTML (not in a tag) - is that OK?
  body.gsub(/([=\'\"\(]\s*)([^\s\'\"\)]+(#{@exts_regex_text}))/) do |match|
    opening_character = $1
    asset_path = $2

    relative_path = Pathname.new(asset_path).relative?

    asset_path = dirpath.join(asset_path).to_s if relative_path

    if @ignore.any? { |r| asset_path.match(r) }
      match
    elsif asset_page = @middleman_app.sitemap.find_resource_by_path(asset_path)
      replacement_path = "/#{asset_page.destination_path}"
      replacement_path = Pathname.new(replacement_path).relative_path_from(dirpath).to_s if relative_path

      "#{opening_character}#{replacement_path}"
    else
      match
    end
  end
end