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.
|
||||
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
|
||||
|
|
|
@ -62,22 +62,12 @@ module Middleman
|
|||
send("#{env}_config", &block)
|
||||
end
|
||||
|
||||
# Alias `extensions` to access registered extensions
|
||||
#
|
||||
# @return [Array<Module>]
|
||||
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<Symbol,Middleman::Extension|Module>]
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -10,10 +10,11 @@
|
|||
<h1>Middleman Config</h1>
|
||||
<a href="../">More meta pages</a>
|
||||
|
||||
<h2>Core Configuration</h2>
|
||||
<ul>
|
||||
<% config.all_settings.each do |setting| %>
|
||||
<li>
|
||||
<b><%= setting.key %></b>:
|
||||
<b><%= setting.key.inspect %></b>:
|
||||
<%= setting.value.inspect %>
|
||||
<% if setting.value_set? %>
|
||||
<br>
|
||||
|
@ -26,6 +27,44 @@
|
|||
</li>
|
||||
<% end %>
|
||||
</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>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -77,7 +78,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 +175,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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue