From b607d70a52ff2c210085e467885505bde9caf53d Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 12 Apr 2013 19:55:44 -0700 Subject: [PATCH 1/8] Simplify configuration a bit, and make extensions raise an error if the user tries to set an invalid extension option. --- middleman-core/lib/middleman-core/configuration.rb | 8 ++------ middleman-core/lib/middleman-core/extensions.rb | 9 ++++----- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/middleman-core/lib/middleman-core/configuration.rb b/middleman-core/lib/middleman-core/configuration.rb index 7d8fc8db..b75c2e8e 100644 --- a/middleman-core/lib/middleman-core/configuration.rb +++ b/middleman-core/lib/middleman-core/configuration.rb @@ -165,16 +165,12 @@ module Middleman # mode and no new settings may be defined. def finalize! @finalized = true + self end # Deep duplicate of the configuration manager def dup - copy = ConfigurationManager.new - @settings.each do |key, setting| - copy_setting = copy.define_setting(setting.key, setting.default, setting.description) - copy_setting.value = setting.value if setting.value_set? - end - copy + ConfigurationManager.new.tap {|c| c.load_settings(self.all_settings) } end # Load in a list of settings diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb index 64df512b..6000877a 100644 --- a/middleman-core/lib/middleman-core/extensions.rb +++ b/middleman-core/lib/middleman-core/extensions.rb @@ -114,15 +114,15 @@ module Middleman attr_accessor :app, :options - def initialize(klass, options_hash={}, &block) - @options = ::Middleman::Configuration::ConfigurationManager.new - @options.load_settings(self.class.config.all_settings) + def initialize(klass, options_hash={}) + @options = self.class.config.dup + @options.finalize! options_hash.each do |k, v| @options[k] = v end - block.call(@options) if block_given? + yield @options if block_given? ext = self klass.after_configuration do @@ -132,7 +132,6 @@ module Middleman end def after_configuration - nil end end From f7cd0e231e1f56f6c8ea1b76c4b3b766fff1e92c Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 12 Apr 2013 19:56:52 -0700 Subject: [PATCH 2/8] Update the extension template for the new Extension class. --- .../templates/extension/lib/lib.rb | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/middleman-core/lib/middleman-core/templates/extension/lib/lib.rb b/middleman-core/lib/middleman-core/templates/extension/lib/lib.rb index 1eb1796c..c2aa42dc 100644 --- a/middleman-core/lib/middleman-core/templates/extension/lib/lib.rb +++ b/middleman-core/lib/middleman-core/templates/extension/lib/lib.rb @@ -2,42 +2,39 @@ require "middleman-core" # Extension namespace -module MyExtension - class << self +module MyExtension < Middleman::Extension + option :my_option, "default", "An example option" - # Called when user `activate`s your extension - def registered(app, options={}) - # Include class methods - # app.extend ClassMethods + def initialize(app, options_hash={}) + # Call super to build options from the options_hash + super - # Include instance methods - # app.send :include, InstanceMethods + # Require libraries only when activated + # require 'necessary/library' - app.after_configuration do - # Do something - end - end - alias :included :registered + # Include helpers or instance methods for the Middleman app + # app.send :include, Helpers + + # set up your extension + # puts options.my_option end - # module ClassMethods - # def a_class_method - # end - # end + def after_configuration + # Do something + end - # module InstanceMethods - # def an_instance_method + # module Helpers + # def a_helper # end # end end - # Register extensions which can be activated # Make sure we have the version of Middleman we expect # ::Middleman::Extensions.register(:extension_name) do # -# # Return the extension module +# # Return the extension class # ::MyExtension # # end From 6bf4059f4a44c231ecc737fa97711acccfbb63f2 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 12 Apr 2013 21:53:44 -0700 Subject: [PATCH 3/8] Rewrite asset hash extension with new extension class --- middleman-more/lib/middleman-more.rb | 2 +- .../middleman-more/extensions/asset_hash.rb | 38 ++++++++++--------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/middleman-more/lib/middleman-more.rb b/middleman-more/lib/middleman-more.rb index df73efa9..c4c771fe 100644 --- a/middleman-more/lib/middleman-more.rb +++ b/middleman-more/lib/middleman-more.rb @@ -83,7 +83,7 @@ module Middleman # to avoid browser caches failing to update to your new content. Middleman::Extensions.register(:asset_hash) do require "middleman-more/extensions/asset_hash" - Middleman::Extensions::AssetHash + Middleman::Extensions::AssetHash::Extension end # AssetHost allows you to setup multiple domains to host your static diff --git a/middleman-more/lib/middleman-more/extensions/asset_hash.rb b/middleman-more/lib/middleman-more/extensions/asset_hash.rb index 2390e1f4..ca710a4b 100644 --- a/middleman-more/lib/middleman-more/extensions/asset_hash.rb +++ b/middleman-more/lib/middleman-more/extensions/asset_hash.rb @@ -1,27 +1,29 @@ module Middleman module Extensions module AssetHash - class << self - def registered(app, options={}) + class Extension < ::Middleman::Extension + option :exts, %w(.jpg .jpeg .png .gif .js .css .otf .woff .eot .ttf .svg), "List of extensions that get asset hashes appended to them." + option :ignore, [], "Regexes of filenames to skip adding asset hashes to" + + def initialize(app, options_hash={}) + super + require 'digest/sha1' require 'rack/test' require 'uri' - - exts = options[:exts] || %w(.jpg .jpeg .png .gif .js .css .otf .woff .eot .ttf .svg) - - # Allow specifying regexes to ignore, plus always ignore apple touch icons - ignore = Array(options[:ignore]) << /^apple-touch-icon/ - - app.ready do - sitemap.register_resource_list_manipulator( - :asset_hash, - AssetHashManager.new(self, exts, ignore) - ) - - use Middleware, :exts => exts, :middleman_app => self, :ignore => ignore - end end - alias :included :registered + + def after_configuration + # Allow specifying regexes to ignore, plus always ignore apple touch icons + ignore = Array(options.ignore) + [/^apple-touch-icon/] + + app.sitemap.register_resource_list_manipulator( + :asset_hash, + AssetHashManager.new(app, options.exts, ignore) + ) + + app.use Middleware, :exts => options.exts, :middleman_app => app, :ignore => ignore + end end # Central class for managing asset_hash extension @@ -38,6 +40,7 @@ module Middleman # 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 @@ -51,7 +54,6 @@ module Middleman next if @ignore.any? { |ignore| Middleman::Util.path_match(ignore, resource.destination_path) } # Render through the Rack interface so middleware and mounted apps get a shot - rack_client = ::Rack::Test::Session.new(@app.class) 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 From 8001dab2580e4487cc5e2e24dff1be394e6bce77 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 12 Apr 2013 21:54:28 -0700 Subject: [PATCH 4/8] Save information about extensions in a discoverable way. This allows us to display extension config information at /__middleman/config/, and also allows users to modify extension settings after they're activated in config.rb with a statement like "extensions[:asset_hash].options.exts += ['.js']". --- .../core_extensions/extensions.rb | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index 44d4b7d1..7515a631 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -62,22 +62,12 @@ module Middleman send("#{env}_config", &block) end - # Alias `extensions` to access registered extensions - # - # @return [Array] - def extensions - @extensions ||= [] - end - # Register a new extension # # @param [Module] extension Extension modules to register # @param [Hash] options Per-extension options hash # @return [void] def register(extension, options={}, &block) - @extensions ||= [] - @extensions += [extension] - if extension.instance_of? Module extend extension if extension.respond_to?(:registered) @@ -87,6 +77,7 @@ module Middleman extension.registered(self, options, &block) end end + extension elsif extension.instance_of?(Class) && extension.ancestors.include?(::Middleman::Extension) extension.new(self, options, &block) end @@ -107,17 +98,24 @@ module Middleman ext_module = if ext.is_a?(Module) ext else - ::Middleman::Extensions.load(ext.to_sym) + ::Middleman::Extensions.load(ext) end if ext_module.nil? logger.error "== Unknown Extension: #{ext}" else logger.debug "== Activating: #{ext}" - self.class.register(ext_module, options, &block) + extensions[ext] = self.class.register(ext_module, options, &block) end end + # Access activated extensions + # + # @return [Hash] + def extensions + @extensions ||= {} + end + # Load features before starting server def initialize super @@ -149,7 +147,7 @@ module Middleman run_hook :after_configuration logger.debug "Loaded extensions:" - self.class.extensions.each do |ext| + self.extensions.each do |ext,_| logger.debug "== Extension: #{ext}" end end From ee11ccb184d41ae666a22ac641ef6ffb6822bba0 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 12 Apr 2013 22:23:20 -0700 Subject: [PATCH 5/8] Reorganize Request a bit --- .../middleman-core/core_extensions/request.rb | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/request.rb b/middleman-core/lib/middleman-core/core_extensions/request.rb index 99f6a9be..af42008b 100644 --- a/middleman-core/lib/middleman-core/core_extensions/request.rb +++ b/middleman-core/lib/middleman-core/core_extensions/request.rb @@ -37,15 +37,7 @@ module Middleman # # @private def reset! - @app = nil - end - - # The shared Rack instance being build - # - # @private - # @return [Rack::Builder] - def app - @app ||= ::Rack::Builder.new + @rack_app = nil end # Get the static instance @@ -74,21 +66,23 @@ module Middleman # @private # @return [Rack::Builder] def to_rack_app(&block) - inner_app = inst(&block) + @rack_app ||= begin + app = ::Rack::Builder.new + app.use Rack::Lint - app.use Rack::Lint + Array(@middleware).each do |klass, options, blockm| + app.use(klass, *options, &block) + end - (@middleware || []).each do |m| - app.use(m[0], *m[1], &m[2]) + inner_app = inst(&block) + app.map("/") { run inner_app } + + Array(@mappings).each do |path, block| + app.map(path, &block) + end + + app end - - app.map("/") { run inner_app } - - (@mappings || []).each do |m| - app.map(m[0], &m[1]) - end - - app end # Prototype app. Used in config.ru From 2d4668f524e172e1f8ee852ea0df85fcaa913d4d Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 12 Apr 2013 22:48:56 -0700 Subject: [PATCH 6/8] Add in the metadata rack app early so it is there whenever middleware grabs the app --- .../lib/middleman-core/preview_server.rb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index fa35983d..330f6c00 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -77,7 +77,15 @@ module Middleman private def new_app opts = @options - @app =::Middleman::Application.server.inst do + server = ::Middleman::Application.server + + # Add in the meta pages application + meta_app = Middleman::MetaPages::Application.new(server) + server.map '/__middleman' do + run meta_app + end + + @app = server.inst do if opts[:environment] config[:environment] = opts[:environment].to_sym end @@ -166,13 +174,6 @@ module Middleman start_file_watcher rack_app = app.class.to_rack_app - - # Add in the meta pages application - meta_app = Middleman::MetaPages::Application.new(app.class.inst) - rack_app.map '/__middleman' do - run meta_app - end - @webrick.mount "/", ::Rack::Handler::WEBrick, rack_app end From 774361bf89f1673e450254cdc904574407dc6eaf Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 12 Apr 2013 22:56:07 -0700 Subject: [PATCH 7/8] Add extensions to meta config page --- .../lib/middleman-core/meta_pages.rb | 5 ++- .../meta_pages/templates/config.html.erb | 45 +++++++++++++++++-- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/middleman-core/lib/middleman-core/meta_pages.rb b/middleman-core/lib/middleman-core/meta_pages.rb index 042ef89d..1c0eec4c 100644 --- a/middleman-core/lib/middleman-core/meta_pages.rb +++ b/middleman-core/lib/middleman-core/meta_pages.rb @@ -45,7 +45,7 @@ module Middleman # Inspect the sitemap def sitemap(env) - resources = @middleman.sitemap.resources(true) + resources = @middleman.inst.sitemap.resources(true) sitemap_tree = SitemapTree.new @@ -58,7 +58,8 @@ module Middleman # Inspect configuration def config(env) - template('config.html.erb', :config => @middleman.config) + + template('config.html.erb', :config => @middleman.inst.config, :extensions => @middleman.inst.extensions, :registered_extensions => Middleman::Extensions.registered.dup) end private diff --git a/middleman-core/lib/middleman-core/meta_pages/templates/config.html.erb b/middleman-core/lib/middleman-core/meta_pages/templates/config.html.erb index c7b3d6b7..f043ec07 100644 --- a/middleman-core/lib/middleman-core/meta_pages/templates/config.html.erb +++ b/middleman-core/lib/middleman-core/meta_pages/templates/config.html.erb @@ -2,18 +2,19 @@ - + Middleman Config - +

Middleman Config

More meta pages +

Core Configuration

    <% config.all_settings.each do |setting| %>
  • - <%= setting.key %>: + <%= setting.key.inspect %>: <%= setting.value.inspect %> <% if setting.value_set? %>
    @@ -26,6 +27,44 @@
  • <% end %>
+ +

Extensions

+
    + <% extensions.each do |ext_name, extension| %> +
  • + <% registered_extensions.delete(ext_name) %> + + <%= ext_name.inspect %> (Active) + <% if extension.is_a?(::Middleman::Extension) && !extension.options.all_settings.empty? %> +
    + Options: +
    +
      + <% extension.options.all_settings.each do |setting| %> +
    • + <%= setting.key.inspect %>: + <%= setting.value.inspect %> + <% if setting.value_set? %> +
      + Default: <%= setting.default.inspect %> + <% else %> + (Default) + <% end %> +
      + <%= setting.description %> +
    • + <% end %> +
    + <% end %> +
  • + + <% end %> + + <% registered_extensions.keys.each do |ext_name| %> +
  • <%= ext_name.inspect %> (Inactive)
  • + <% end %> +
+ From 6fcbac0368027a86e7ec8e2c89dfcfe499972ab6 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 12 Apr 2013 23:30:19 -0700 Subject: [PATCH 8/8] Advertise meta pages on startup --- middleman-core/lib/middleman-core/preview_server.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index 330f6c00..7296712c 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -19,6 +19,7 @@ module Middleman mount_instance logger.info "== The Middleman is standing watch at http://#{host}:#{port}" + logger.info "== Inspect your site configuration at http://#{host}:#{port}/__middleman/" @initialized ||= false unless @initialized