diff --git a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb index fe6a3fd7..2ca53483 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -174,28 +174,22 @@ module Middleman::CoreExtensions end data = {} - content = nil - return [data, content] unless app.files.exists?(full_path) + return [data, nil] if !app.files.exists?(full_path) || ::Middleman::Util.binary?(full_path) - if !::Middleman::Util.binary?(full_path) - content = File.read(full_path) - - begin - if content =~ /\A.*coding:/ - lines = content.split(/\n/) - lines.shift - content = lines.join("\n") - end - - if result = parse_yaml_front_matter(content) - data, content = result - elsif result = parse_json_front_matter(content) - data, content = result - end - rescue - # Probably a binary file, move on + content = File.read(full_path) + + begin + if content =~ /\A.*coding:/ + lines = content.split(/\n/) + lines.shift + content = lines.join("\n") end + + result = parse_yaml_front_matter(content) || parse_json_front_matter(content) + return result if result + rescue + # Probably a binary file, move on end [data, content] diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb index 1956bf6a..93fed5b7 100644 --- a/middleman-core/lib/middleman-core/extensions.rb +++ b/middleman-core/lib/middleman-core/extensions.rb @@ -136,53 +136,17 @@ module Middleman attr_accessor :options attr_reader :app - def initialize(klass, options_hash={}) + def initialize(klass, options_hash={}, &block) @_helpers = [] + @klass = klass - @options = self.class.config.dup - @options.finalize! + setup_options(options_hash, &block) + setup_app_reference_when_available - options_hash.each do |k, v| - @options[k] = v - end - - yield @options if block_given? - - ext = self - - klass.initialized do - ext.app = self - end - - if ext.respond_to?(:before_configuration) - klass.before_configuration do - ext.before_configuration - end - end - - klass.instance_available do - ext.app ||= self - end - - klass.after_configuration do - if ext.respond_to?(:after_configuration) - ext.after_configuration - end - - if ext.respond_to?(:manipulate_resource_list) - ext.app.sitemap.register_resource_list_manipulator(ext.class.extension_name, ext) - end - end - - if ext.respond_to?(:after_build) - klass.after_build do |builder| - if ext.method(:after_build).arity === 1 - ext.after_build(builder) - else - ext.after_build - end - end - end + # Bind app hooks to local methods + bind_before_configuration + bind_after_configuration + bind_after_build end def app=(app) @@ -192,5 +156,65 @@ module Middleman app.class.send(:include, m) end end + + protected + + def setup_options(options_hash, &block) + @options = self.class.config.dup + @options.finalize! + + options_hash.each do |k, v| + @options[k] = v + end + + yield @options if block_given? + end + + def setup_app_reference_when_available + ext = self + + @klass.initialized do + ext.app = self + end + + @klass.instance_available do + ext.app ||= self + end + end + + def bind_before_configuration + ext = self + if ext.respond_to?(:before_configuration) + @klass.before_configuration do + ext.before_configuration + end + end + end + + def bind_after_configuration + ext = self + @klass.after_configuration do + if ext.respond_to?(:after_configuration) + ext.after_configuration + end + + if ext.respond_to?(:manipulate_resource_list) + ext.app.sitemap.register_resource_list_manipulator(ext.class.extension_name, ext) + end + end + end + + def bind_after_build + ext = self + if ext.respond_to?(:after_build) + @klass.after_build do |builder| + if ext.method(:after_build).arity === 1 + ext.after_build(builder) + else + ext.after_build + end + end + end + end end end diff --git a/middleman-core/lib/middleman-more/core_extensions/i18n.rb b/middleman-core/lib/middleman-more/core_extensions/i18n.rb index e8db66ae..a1d19f1f 100644 --- a/middleman-core/lib/middleman-more/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-more/core_extensions/i18n.rb @@ -173,15 +173,15 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension localized_page_id = ::I18n.t("paths.#{page_id}", :default => page_id, :fallback => []) - if @mount_at_root == lang - prefix = "/" + prefix = if @mount_at_root == lang + "/" else replacement = options[:lang_map].fetch(lang, lang) - prefix = options[:path].sub(":locale", replacement.to_s) + options[:path].sub(":locale", replacement.to_s) end path = ::Middleman::Util.normalize_path( - File.join(prefix, path.sub(page_id, localized_page_id)) + File.join(prefix, path.sub(page_id, localized_page_id)) ) @_localization_data[path] = [lang, path, localized_page_id] diff --git a/middleman-core/lib/middleman-more/extensions/asset_hash.rb b/middleman-core/lib/middleman-more/extensions/asset_hash.rb index 70b6dd1d..447cfaf1 100644 --- a/middleman-core/lib/middleman-more/extensions/asset_hash.rb +++ b/middleman-core/lib/middleman-more/extensions/asset_hash.rb @@ -20,10 +20,11 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension # Update the main sitemap resource list # @return [void] def manipulate_resource_list(resources) + @rack_client ||= ::Rack::Test::Session.new(app.class.to_rack_app) + # Process resources in order: binary images and fonts, then SVG, then JS/CSS. # This is so by the time we get around to the text files (which may reference # images and fonts) the static assets' hashes are already calculated. - rack_client = ::Rack::Test::Session.new(app.class.to_rack_app) resources.sort_by do |a| if %w(.svg).include? a.ext 0 @@ -32,18 +33,24 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension else -1 end - end.each do |resource| - next unless options.exts.include? resource.ext - next if @ignore.any? { |ignore| Middleman::Util.path_match(ignore, resource.destination_path) } + end.each(&method(:manipulate_single_resource)) + end - # Render through the Rack interface so middleware and mounted apps get a shot - response = rack_client.get(URI.escape(resource.destination_path), {}, { "bypass_asset_hash" => "true" }) - raise "#{resource.path} should be in the sitemap!" unless response.status == 200 + def manipulate_single_resource(resource) + return unless options.exts.include?(resource.ext) + return if ignored_resource?(resource) - digest = Digest::SHA1.hexdigest(response.body)[0..7] + # Render through the Rack interface so middleware and mounted apps get a shot + response = @rack_client.get(URI.escape(resource.destination_path), {}, { "bypass_asset_hash" => "true" }) + raise "#{resource.path} should be in the sitemap!" unless response.status == 200 - resource.destination_path = resource.destination_path.sub(/\.(\w+)$/) { |ext| "-#{digest}#{ext}" } - end + digest = Digest::SHA1.hexdigest(response.body)[0..7] + + resource.destination_path = resource.destination_path.sub(/\.(\w+)$/) { |ext| "-#{digest}#{ext}" } + end + + def ignored_resource?(resource) + @ignore.any? { |ignore| Middleman::Util.path_match(ignore, resource.destination_path) } end # The asset hash middleware is responsible for rewriting references to @@ -64,38 +71,44 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension return [status, headers, response] if env["bypass_asset_hash"] == 'true' path = @middleman_app.full_path(env["PATH_INFO"]) - dirpath = Pathname.new(File.dirname(path)) if path =~ /(^\/$)|(\.(htm|html|php|css|js)$)/ body = ::Middleman::Util.extract_response_text(response) - if body - # 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 - - status, headers, response = Rack::Response.new(body, status, headers).finish + status, headers, response = Rack::Response.new(rewrite_paths(body, path), status, headers).finish end end + [status, headers, response] end + + private + + 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 + end end diff --git a/middleman-core/lib/middleman-more/extensions/minify_javascript.rb b/middleman-core/lib/middleman-more/extensions/minify_javascript.rb index fb174ce1..9e9f40df 100644 --- a/middleman-core/lib/middleman-more/extensions/minify_javascript.rb +++ b/middleman-core/lib/middleman-more/extensions/minify_javascript.rb @@ -44,34 +44,19 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension path = env["PATH_INFO"] begin - if (path.end_with?('.html') || path.end_with?('.php')) && @inline + if @inline && (path.end_with?('.html') || path.end_with?('.php')) uncompressed_source = ::Middleman::Util.extract_response_text(response) - minified = uncompressed_source.gsub(/(]*>\s*(?:\/\/(?:(?:)|(?:\]\]>)))?\s*<\/script>)/m) do |match| - first = $1 - javascript = $2 - last = $3 - - # Only compress script tags that contain JavaScript (as opposed - # to something like jQuery templates, identified with a "text/html" - # type. - if first =~ /