Merge pull request #861 from bhollis/extensions
A bunch of extensions and config meta pages work
This commit is contained in:
commit
a2f0cc263a
|
@ -165,16 +165,12 @@ module Middleman
|
||||||
# mode and no new settings may be defined.
|
# mode and no new settings may be defined.
|
||||||
def finalize!
|
def finalize!
|
||||||
@finalized = true
|
@finalized = true
|
||||||
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
# Deep duplicate of the configuration manager
|
# Deep duplicate of the configuration manager
|
||||||
def dup
|
def dup
|
||||||
copy = ConfigurationManager.new
|
ConfigurationManager.new.tap {|c| c.load_settings(self.all_settings) }
|
||||||
@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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Load in a list of settings
|
# Load in a list of settings
|
||||||
|
|
|
@ -62,22 +62,12 @@ module Middleman
|
||||||
send("#{env}_config", &block)
|
send("#{env}_config", &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Alias `extensions` to access registered extensions
|
|
||||||
#
|
|
||||||
# @return [Array<Module>]
|
|
||||||
def extensions
|
|
||||||
@extensions ||= []
|
|
||||||
end
|
|
||||||
|
|
||||||
# Register a new extension
|
# Register a new extension
|
||||||
#
|
#
|
||||||
# @param [Module] extension Extension modules to register
|
# @param [Module] extension Extension modules to register
|
||||||
# @param [Hash] options Per-extension options hash
|
# @param [Hash] options Per-extension options hash
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def register(extension, options={}, &block)
|
def register(extension, options={}, &block)
|
||||||
@extensions ||= []
|
|
||||||
@extensions += [extension]
|
|
||||||
|
|
||||||
if extension.instance_of? Module
|
if extension.instance_of? Module
|
||||||
extend extension
|
extend extension
|
||||||
if extension.respond_to?(:registered)
|
if extension.respond_to?(:registered)
|
||||||
|
@ -87,6 +77,7 @@ module Middleman
|
||||||
extension.registered(self, options, &block)
|
extension.registered(self, options, &block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
extension
|
||||||
elsif extension.instance_of?(Class) && extension.ancestors.include?(::Middleman::Extension)
|
elsif extension.instance_of?(Class) && extension.ancestors.include?(::Middleman::Extension)
|
||||||
extension.new(self, options, &block)
|
extension.new(self, options, &block)
|
||||||
end
|
end
|
||||||
|
@ -107,17 +98,24 @@ module Middleman
|
||||||
ext_module = if ext.is_a?(Module)
|
ext_module = if ext.is_a?(Module)
|
||||||
ext
|
ext
|
||||||
else
|
else
|
||||||
::Middleman::Extensions.load(ext.to_sym)
|
::Middleman::Extensions.load(ext)
|
||||||
end
|
end
|
||||||
|
|
||||||
if ext_module.nil?
|
if ext_module.nil?
|
||||||
logger.error "== Unknown Extension: #{ext}"
|
logger.error "== Unknown Extension: #{ext}"
|
||||||
else
|
else
|
||||||
logger.debug "== Activating: #{ext}"
|
logger.debug "== Activating: #{ext}"
|
||||||
self.class.register(ext_module, options, &block)
|
extensions[ext] = self.class.register(ext_module, options, &block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Access activated extensions
|
||||||
|
#
|
||||||
|
# @return [Hash<Symbol,Middleman::Extension|Module>]
|
||||||
|
def extensions
|
||||||
|
@extensions ||= {}
|
||||||
|
end
|
||||||
|
|
||||||
# Load features before starting server
|
# Load features before starting server
|
||||||
def initialize
|
def initialize
|
||||||
super
|
super
|
||||||
|
@ -149,7 +147,7 @@ module Middleman
|
||||||
run_hook :after_configuration
|
run_hook :after_configuration
|
||||||
|
|
||||||
logger.debug "Loaded extensions:"
|
logger.debug "Loaded extensions:"
|
||||||
self.class.extensions.each do |ext|
|
self.extensions.each do |ext,_|
|
||||||
logger.debug "== Extension: #{ext}"
|
logger.debug "== Extension: #{ext}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,15 +37,7 @@ module Middleman
|
||||||
#
|
#
|
||||||
# @private
|
# @private
|
||||||
def reset!
|
def reset!
|
||||||
@app = nil
|
@rack_app = nil
|
||||||
end
|
|
||||||
|
|
||||||
# The shared Rack instance being build
|
|
||||||
#
|
|
||||||
# @private
|
|
||||||
# @return [Rack::Builder]
|
|
||||||
def app
|
|
||||||
@app ||= ::Rack::Builder.new
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get the static instance
|
# Get the static instance
|
||||||
|
@ -74,21 +66,23 @@ module Middleman
|
||||||
# @private
|
# @private
|
||||||
# @return [Rack::Builder]
|
# @return [Rack::Builder]
|
||||||
def to_rack_app(&block)
|
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|
|
inner_app = inst(&block)
|
||||||
app.use(m[0], *m[1], &m[2])
|
app.map("/") { run inner_app }
|
||||||
|
|
||||||
|
Array(@mappings).each do |path, block|
|
||||||
|
app.map(path, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
app
|
||||||
end
|
end
|
||||||
|
|
||||||
app.map("/") { run inner_app }
|
|
||||||
|
|
||||||
(@mappings || []).each do |m|
|
|
||||||
app.map(m[0], &m[1])
|
|
||||||
end
|
|
||||||
|
|
||||||
app
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Prototype app. Used in config.ru
|
# Prototype app. Used in config.ru
|
||||||
|
|
|
@ -114,15 +114,15 @@ module Middleman
|
||||||
|
|
||||||
attr_accessor :app, :options
|
attr_accessor :app, :options
|
||||||
|
|
||||||
def initialize(klass, options_hash={}, &block)
|
def initialize(klass, options_hash={})
|
||||||
@options = ::Middleman::Configuration::ConfigurationManager.new
|
@options = self.class.config.dup
|
||||||
@options.load_settings(self.class.config.all_settings)
|
@options.finalize!
|
||||||
|
|
||||||
options_hash.each do |k, v|
|
options_hash.each do |k, v|
|
||||||
@options[k] = v
|
@options[k] = v
|
||||||
end
|
end
|
||||||
|
|
||||||
block.call(@options) if block_given?
|
yield @options if block_given?
|
||||||
|
|
||||||
ext = self
|
ext = self
|
||||||
klass.after_configuration do
|
klass.after_configuration do
|
||||||
|
@ -132,7 +132,6 @@ module Middleman
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_configuration
|
def after_configuration
|
||||||
|
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -45,7 +45,7 @@ module Middleman
|
||||||
|
|
||||||
# Inspect the sitemap
|
# Inspect the sitemap
|
||||||
def sitemap(env)
|
def sitemap(env)
|
||||||
resources = @middleman.sitemap.resources(true)
|
resources = @middleman.inst.sitemap.resources(true)
|
||||||
|
|
||||||
sitemap_tree = SitemapTree.new
|
sitemap_tree = SitemapTree.new
|
||||||
|
|
||||||
|
@ -58,7 +58,8 @@ module Middleman
|
||||||
|
|
||||||
# Inspect configuration
|
# Inspect configuration
|
||||||
def config(env)
|
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
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -10,10 +10,11 @@
|
||||||
<h1>Middleman Config</h1>
|
<h1>Middleman Config</h1>
|
||||||
<a href="../">More meta pages</a>
|
<a href="../">More meta pages</a>
|
||||||
|
|
||||||
|
<h2>Core Configuration</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<% config.all_settings.each do |setting| %>
|
<% config.all_settings.each do |setting| %>
|
||||||
<li>
|
<li>
|
||||||
<b><%= setting.key %></b>:
|
<b><%= setting.key.inspect %></b>:
|
||||||
<%= setting.value.inspect %>
|
<%= setting.value.inspect %>
|
||||||
<% if setting.value_set? %>
|
<% if setting.value_set? %>
|
||||||
<br>
|
<br>
|
||||||
|
@ -26,6 +27,44 @@
|
||||||
</li>
|
</li>
|
||||||
<% end %>
|
<% end %>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<h2>Extensions</h2>
|
||||||
|
<ul>
|
||||||
|
<% extensions.each do |ext_name, extension| %>
|
||||||
|
<li>
|
||||||
|
<% registered_extensions.delete(ext_name) %>
|
||||||
|
|
||||||
|
<b><%= ext_name.inspect %></b> (Active)
|
||||||
|
<% if extension.is_a?(::Middleman::Extension) && !extension.options.all_settings.empty? %>
|
||||||
|
<br>
|
||||||
|
<b>Options:</b>
|
||||||
|
<br>
|
||||||
|
<ul>
|
||||||
|
<% extension.options.all_settings.each do |setting| %>
|
||||||
|
<li>
|
||||||
|
<b><%= setting.key.inspect %></b>:
|
||||||
|
<%= setting.value.inspect %>
|
||||||
|
<% if setting.value_set? %>
|
||||||
|
<br>
|
||||||
|
Default: <%= setting.default.inspect %>
|
||||||
|
<% else %>
|
||||||
|
(Default)
|
||||||
|
<% end %>
|
||||||
|
<br>
|
||||||
|
<i><%= setting.description %></i>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
<% end %>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% registered_extensions.keys.each do |ext_name| %>
|
||||||
|
<li><b><%= ext_name.inspect %></b> (Inactive)</li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ module Middleman
|
||||||
|
|
||||||
mount_instance
|
mount_instance
|
||||||
logger.info "== The Middleman is standing watch at http://#{host}:#{port}"
|
logger.info "== The Middleman is standing watch at http://#{host}:#{port}"
|
||||||
|
logger.info "== Inspect your site configuration at http://#{host}:#{port}/__middleman/"
|
||||||
|
|
||||||
@initialized ||= false
|
@initialized ||= false
|
||||||
unless @initialized
|
unless @initialized
|
||||||
|
@ -77,7 +78,15 @@ module Middleman
|
||||||
private
|
private
|
||||||
def new_app
|
def new_app
|
||||||
opts = @options
|
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]
|
if opts[:environment]
|
||||||
config[:environment] = opts[:environment].to_sym
|
config[:environment] = opts[:environment].to_sym
|
||||||
end
|
end
|
||||||
|
@ -166,13 +175,6 @@ module Middleman
|
||||||
start_file_watcher
|
start_file_watcher
|
||||||
|
|
||||||
rack_app = app.class.to_rack_app
|
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
|
@webrick.mount "/", ::Rack::Handler::WEBrick, rack_app
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,42 +2,39 @@
|
||||||
require "middleman-core"
|
require "middleman-core"
|
||||||
|
|
||||||
# Extension namespace
|
# Extension namespace
|
||||||
module MyExtension
|
module MyExtension < Middleman::Extension
|
||||||
class << self
|
option :my_option, "default", "An example option"
|
||||||
|
|
||||||
# Called when user `activate`s your extension
|
def initialize(app, options_hash={})
|
||||||
def registered(app, options={})
|
# Call super to build options from the options_hash
|
||||||
# Include class methods
|
super
|
||||||
# app.extend ClassMethods
|
|
||||||
|
|
||||||
# Include instance methods
|
# Require libraries only when activated
|
||||||
# app.send :include, InstanceMethods
|
# require 'necessary/library'
|
||||||
|
|
||||||
app.after_configuration do
|
# Include helpers or instance methods for the Middleman app
|
||||||
# Do something
|
# app.send :include, Helpers
|
||||||
end
|
|
||||||
end
|
# set up your extension
|
||||||
alias :included :registered
|
# puts options.my_option
|
||||||
end
|
end
|
||||||
|
|
||||||
# module ClassMethods
|
def after_configuration
|
||||||
# def a_class_method
|
# Do something
|
||||||
# end
|
end
|
||||||
# end
|
|
||||||
|
|
||||||
# module InstanceMethods
|
# module Helpers
|
||||||
# def an_instance_method
|
# def a_helper
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Register extensions which can be activated
|
# Register extensions which can be activated
|
||||||
# Make sure we have the version of Middleman we expect
|
# Make sure we have the version of Middleman we expect
|
||||||
# ::Middleman::Extensions.register(:extension_name) do
|
# ::Middleman::Extensions.register(:extension_name) do
|
||||||
#
|
#
|
||||||
# # Return the extension module
|
# # Return the extension class
|
||||||
# ::MyExtension
|
# ::MyExtension
|
||||||
#
|
#
|
||||||
# end
|
# end
|
||||||
|
|
|
@ -83,7 +83,7 @@ module Middleman
|
||||||
# to avoid browser caches failing to update to your new content.
|
# to avoid browser caches failing to update to your new content.
|
||||||
Middleman::Extensions.register(:asset_hash) do
|
Middleman::Extensions.register(:asset_hash) do
|
||||||
require "middleman-more/extensions/asset_hash"
|
require "middleman-more/extensions/asset_hash"
|
||||||
Middleman::Extensions::AssetHash
|
Middleman::Extensions::AssetHash::Extension
|
||||||
end
|
end
|
||||||
|
|
||||||
# AssetHost allows you to setup multiple domains to host your static
|
# AssetHost allows you to setup multiple domains to host your static
|
||||||
|
|
|
@ -1,27 +1,29 @@
|
||||||
module Middleman
|
module Middleman
|
||||||
module Extensions
|
module Extensions
|
||||||
module AssetHash
|
module AssetHash
|
||||||
class << self
|
class Extension < ::Middleman::Extension
|
||||||
def registered(app, options={})
|
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 'digest/sha1'
|
||||||
require 'rack/test'
|
require 'rack/test'
|
||||||
require 'uri'
|
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
|
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
|
end
|
||||||
|
|
||||||
# Central class for managing asset_hash extension
|
# 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.
|
# 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
|
# 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.
|
# 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|
|
resources.sort_by do |a|
|
||||||
if %w(.svg).include? a.ext
|
if %w(.svg).include? a.ext
|
||||||
0
|
0
|
||||||
|
@ -51,7 +54,6 @@ module Middleman
|
||||||
next if @ignore.any? { |ignore| Middleman::Util.path_match(ignore, resource.destination_path) }
|
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
|
# 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" })
|
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
|
raise "#{resource.path} should be in the sitemap!" unless response.status == 200
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue