Merge pull request #1135 from middleman/config_context
Put all config.rb access into a jail.
This commit is contained in:
commit
572bf533f8
|
@ -1,12 +1,16 @@
|
||||||
set :layout, false
|
set :layout, false
|
||||||
|
|
||||||
module ExtensionA
|
class ExtensionA < ::Middleman::Extension
|
||||||
class << self
|
helpers do
|
||||||
def registered(app, options={})
|
def get_option(key)
|
||||||
app.set :a_options, options
|
extensions[:extension_a].options[key]
|
||||||
end
|
end
|
||||||
alias :included :registered
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
option :hello, '', ''
|
||||||
|
option :hola, '', ''
|
||||||
end
|
end
|
||||||
|
|
||||||
activate ExtensionA, :hello => "world", :hola => "mundo"
|
ExtensionA.register
|
||||||
|
|
||||||
|
activate :extension_a, :hello => "world", :hola => "mundo"
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
<% a_options.each do |k, v| %>
|
hello: <%= get_option(:hello) %>
|
||||||
<%= k %>: <%= v%>
|
hola: <%= get_option(:hola) %>
|
||||||
<% end %>
|
|
|
@ -1,9 +1,17 @@
|
||||||
class ExtensionOne < ::Middleman::Extension
|
class ExtensionOne < ::Middleman::Extension
|
||||||
|
helpers do
|
||||||
|
def extension_two_was_activated
|
||||||
|
extensions[:extension_one].extension_two_was_activated
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :extension_two_was_activated
|
||||||
|
|
||||||
def initialize(app, options_hash={})
|
def initialize(app, options_hash={})
|
||||||
super
|
super
|
||||||
|
|
||||||
after_extension_activated :extension_two do
|
after_extension_activated :extension_two do
|
||||||
app.set :extension_two_was_activated, true
|
@extension_two_was_activated = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -11,11 +19,19 @@ end
|
||||||
ExtensionOne.register
|
ExtensionOne.register
|
||||||
|
|
||||||
class ExtensionTwo < ::Middleman::Extension
|
class ExtensionTwo < ::Middleman::Extension
|
||||||
|
helpers do
|
||||||
|
def extension_one_was_activated
|
||||||
|
extensions[:extension_two].extension_one_was_activated
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :extension_one_was_activated
|
||||||
|
|
||||||
def initialize(app, options_hash={})
|
def initialize(app, options_hash={})
|
||||||
super
|
super
|
||||||
|
|
||||||
after_extension_activated :extension_one do
|
after_extension_activated :extension_one do
|
||||||
app.set :extension_one_was_activated, true
|
@extension_one_was_activated = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,10 +20,13 @@ require 'vendored-middleman-deps/hooks-0.2.0/lib/hooks'
|
||||||
require 'middleman-core/logger'
|
require 'middleman-core/logger'
|
||||||
|
|
||||||
require 'middleman-core/sitemap'
|
require 'middleman-core/sitemap'
|
||||||
|
require 'middleman-core/sitemap/store'
|
||||||
|
|
||||||
require 'middleman-core/configuration'
|
require 'middleman-core/configuration'
|
||||||
require 'middleman-core/core_extensions'
|
require 'middleman-core/core_extensions'
|
||||||
|
|
||||||
|
require 'middleman-core/config_context'
|
||||||
|
|
||||||
# Core Middleman Class
|
# Core Middleman Class
|
||||||
module Middleman
|
module Middleman
|
||||||
class Application
|
class Application
|
||||||
|
@ -150,48 +153,52 @@ module Middleman
|
||||||
# extensions see updated frontmatter!
|
# extensions see updated frontmatter!
|
||||||
register Middleman::CoreExtensions::FrontMatter
|
register Middleman::CoreExtensions::FrontMatter
|
||||||
|
|
||||||
# Sitemap
|
# Sitemap Config options and public api
|
||||||
register Middleman::Sitemap
|
register Middleman::Sitemap
|
||||||
|
|
||||||
# Setup external helpers
|
# Setup external helpers
|
||||||
register Middleman::CoreExtensions::ExternalHelpers
|
register Middleman::CoreExtensions::ExternalHelpers
|
||||||
|
|
||||||
# with_layout and page routing
|
# Reference to Logger singleton
|
||||||
include Middleman::CoreExtensions::Routing
|
|
||||||
|
|
||||||
attr_reader :logger
|
attr_reader :logger
|
||||||
|
|
||||||
|
# New container for config.rb commands
|
||||||
|
attr_reader :config_context
|
||||||
|
|
||||||
|
# Reference to Sitemap
|
||||||
|
attr_reader :sitemap
|
||||||
|
|
||||||
|
# Template cache
|
||||||
|
attr_reader :cache
|
||||||
|
|
||||||
# Initialize the Middleman project
|
# Initialize the Middleman project
|
||||||
def initialize(&block)
|
def initialize(&block)
|
||||||
|
@cache = ::Tilt::Cache.new
|
||||||
@logger = ::Middleman::Logger.singleton
|
@logger = ::Middleman::Logger.singleton
|
||||||
|
@config_context = ConfigContext.new(self)
|
||||||
# Clear the static class cache
|
|
||||||
cache.clear
|
|
||||||
|
|
||||||
# Setup the default values from calls to set before initialization
|
# Setup the default values from calls to set before initialization
|
||||||
self.class.config.load_settings(self.class.superclass.config.all_settings)
|
self.class.config.load_settings(self.class.superclass.config.all_settings)
|
||||||
|
|
||||||
|
# Initialize the Sitemap
|
||||||
|
@sitemap = ::Middleman::Sitemap::Store.new(self)
|
||||||
|
|
||||||
if Object.const_defined?(:Encoding)
|
if Object.const_defined?(:Encoding)
|
||||||
Encoding.default_internal = config[:encoding]
|
Encoding.default_internal = config[:encoding]
|
||||||
Encoding.default_external = config[:encoding]
|
Encoding.default_external = config[:encoding]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Evaluate a passed block if given
|
# Evaluate a passed block if given
|
||||||
instance_exec(&block) if block_given?
|
@config_context.instance_exec(&block) if block_given?
|
||||||
|
|
||||||
config[:source] = ENV['MM_SOURCE'] if ENV['MM_SOURCE']
|
config[:source] = ENV['MM_SOURCE'] if ENV['MM_SOURCE']
|
||||||
|
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
# Shared cache instance
|
def add_to_config_context(name, &func)
|
||||||
#
|
@config_context.define_singleton_method(name, &func)
|
||||||
# @private
|
|
||||||
# @return [Middleman::Util::Cache] The cache
|
|
||||||
def self.cache
|
|
||||||
@_cache ||= ::Tilt::Cache.new
|
|
||||||
end
|
end
|
||||||
delegate :cache, :to => :"self.class"
|
|
||||||
|
|
||||||
# Whether we're in development mode
|
# Whether we're in development mode
|
||||||
# @return [Boolean] If we're in dev mode
|
# @return [Boolean] If we're in dev mode
|
||||||
|
|
|
@ -68,6 +68,7 @@ module Middleman::Cli
|
||||||
action BuildAction.new(self, opts)
|
action BuildAction.new(self, opts)
|
||||||
|
|
||||||
self.class.shared_instance.run_hook :after_build, self
|
self.class.shared_instance.run_hook :after_build, self
|
||||||
|
self.class.shared_instance.config_context.execute_after_build_callbacks(self)
|
||||||
|
|
||||||
if self.had_errors && !self.debugging
|
if self.had_errors && !self.debugging
|
||||||
msg = 'There were errors during this build'
|
msg = 'There were errors during this build'
|
||||||
|
@ -110,7 +111,7 @@ module Middleman::Cli
|
||||||
def initialize(base, config={})
|
def initialize(base, config={})
|
||||||
@app = base.class.shared_instance
|
@app = base.class.shared_instance
|
||||||
@source_dir = Pathname(@app.source_dir)
|
@source_dir = Pathname(@app.source_dir)
|
||||||
@build_dir = Pathname(@app.build_dir)
|
@build_dir = Pathname(@app.config[:build_dir])
|
||||||
@to_clean = Set.new
|
@to_clean = Set.new
|
||||||
|
|
||||||
@logger = @app.logger
|
@logger = @app.logger
|
||||||
|
@ -190,7 +191,7 @@ module Middleman::Cli
|
||||||
logger.debug '== Checking for Compass sprites'
|
logger.debug '== Checking for Compass sprites'
|
||||||
|
|
||||||
# Double-check for compass sprites
|
# Double-check for compass sprites
|
||||||
@app.files.find_new_files((@source_dir + @app.images_dir).relative_path_from(@app.root_path))
|
@app.files.find_new_files((@source_dir + @app.config[:images_dir]).relative_path_from(@app.root_path))
|
||||||
@app.sitemap.ensure_resource_list_updated!
|
@app.sitemap.ensure_resource_list_updated!
|
||||||
|
|
||||||
# Sort paths to be built by the above order. This is primarily so Compass can
|
# Sort paths to be built by the above order. This is primarily so Compass can
|
||||||
|
|
|
@ -29,7 +29,7 @@ module Middleman::Cli
|
||||||
|
|
||||||
@app =::Middleman::Application.server.inst do
|
@app =::Middleman::Application.server.inst do
|
||||||
if opts[:environment]
|
if opts[:environment]
|
||||||
set :environment, opts[:environment].to_sym
|
config[:environment] = opts[:environment].to_sym
|
||||||
end
|
end
|
||||||
|
|
||||||
logger(opts[:debug] ? 0 : 1, opts[:instrumenting] || false)
|
logger(opts[:debug] ? 0 : 1, opts[:instrumenting] || false)
|
||||||
|
|
66
middleman-core/lib/middleman-core/config_context.rb
Normal file
66
middleman-core/lib/middleman-core/config_context.rb
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
module Middleman
|
||||||
|
class ConfigContext
|
||||||
|
# with_layout and page routing
|
||||||
|
include Middleman::CoreExtensions::Routing
|
||||||
|
|
||||||
|
attr_reader :app
|
||||||
|
|
||||||
|
# Whitelist methods that can reach out.
|
||||||
|
delegate :config, :logger, :activate, :use, :map, :mime_type, :data, :helpers, :template_extensions, :root, :to => :app
|
||||||
|
|
||||||
|
def initialize(app)
|
||||||
|
@app = app
|
||||||
|
@ready_callbacks = []
|
||||||
|
@after_build_callbacks = []
|
||||||
|
@after_configuration_callbacks = []
|
||||||
|
@configure_callbacks = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def ready(&block)
|
||||||
|
@ready_callbacks << block
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute_ready_callbacks
|
||||||
|
@ready_callbacks.each do |b|
|
||||||
|
instance_exec(&b)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def after_build(&block)
|
||||||
|
@after_build_callbacks << block
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute_after_build_callbacks(*args)
|
||||||
|
@after_build_callbacks.each do |b|
|
||||||
|
instance_exec(*args, &b)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def after_configuration(&block)
|
||||||
|
@after_configuration_callbacks << block
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute_after_configuration_callbacks
|
||||||
|
@after_configuration_callbacks.each do |b|
|
||||||
|
instance_exec(&b)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def configure(key, &block)
|
||||||
|
@configure_callbacks[key] ||= []
|
||||||
|
@configure_callbacks[key] << block
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute_configure_callbacks(key)
|
||||||
|
@configure_callbacks[key] ||= []
|
||||||
|
@configure_callbacks[key].each do |b|
|
||||||
|
instance_exec(&b)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set(key, default=nil, &block)
|
||||||
|
config.define_setting(key, default) unless config.defines_setting?(key)
|
||||||
|
@app.config[key] = block_given? ? block : default
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -5,6 +5,7 @@ module Middleman
|
||||||
module Global
|
module Global
|
||||||
def self.included(app)
|
def self.included(app)
|
||||||
app.send :extend, ClassMethods
|
app.send :extend, ClassMethods
|
||||||
|
app.send :delegate, :config, :to => :"self.class"
|
||||||
end
|
end
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
|
@ -13,75 +14,6 @@ module Middleman
|
||||||
def config
|
def config
|
||||||
@_config ||= ConfigurationManager.new
|
@_config ||= ConfigurationManager.new
|
||||||
end
|
end
|
||||||
|
|
||||||
# Set attributes (global variables)
|
|
||||||
#
|
|
||||||
# @deprecated Prefer accessing settings through "config".
|
|
||||||
#
|
|
||||||
# @param [Symbol] key Name of the attribue
|
|
||||||
# @param default Attribute value
|
|
||||||
# @return [void]
|
|
||||||
def set(key, default=nil, &block)
|
|
||||||
config.define_setting(key, default) unless config.defines_setting?(key)
|
|
||||||
@inst.set(key, default, &block) if @inst
|
|
||||||
end
|
|
||||||
|
|
||||||
# Access global settings as methods, to preserve compatibility with
|
|
||||||
# old Middleman.
|
|
||||||
#
|
|
||||||
# @deprecated Prefer accessing settings through "config".
|
|
||||||
def method_missing(method, *args)
|
|
||||||
if config.defines_setting? method
|
|
||||||
config[method]
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Needed so that method_missing makes sense
|
|
||||||
def respond_to?(method, include_private = false)
|
|
||||||
super || config.defines_setting?(method)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def config
|
|
||||||
self.class.config
|
|
||||||
end
|
|
||||||
|
|
||||||
# Backwards compatibilty with old Sinatra template interface
|
|
||||||
#
|
|
||||||
# @deprecated Prefer accessing settings through "config".
|
|
||||||
#
|
|
||||||
# @return [ConfigurationManager]
|
|
||||||
alias :settings :config
|
|
||||||
|
|
||||||
# Set attributes (global variables)
|
|
||||||
#
|
|
||||||
# @deprecated Prefer accessing settings through "config".
|
|
||||||
#
|
|
||||||
# @param [Symbol] key Name of the attribue
|
|
||||||
# @param value Attribute value
|
|
||||||
# @return [void]
|
|
||||||
def set(key, value=nil, &block)
|
|
||||||
value = block if block_given?
|
|
||||||
config[key] = value
|
|
||||||
end
|
|
||||||
|
|
||||||
# Access global settings as methods, to preserve compatibility with
|
|
||||||
# old Middleman.
|
|
||||||
#
|
|
||||||
# @deprecated Prefer accessing settings through "config".
|
|
||||||
def method_missing(method, *args)
|
|
||||||
if config.defines_setting? method
|
|
||||||
config[method]
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Needed so that method_missing makes sense
|
|
||||||
def respond_to?(method, include_private = false)
|
|
||||||
super || config.defines_setting?(method)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -159,11 +159,18 @@ module Middleman
|
||||||
local_config = File.join(root, 'config.rb')
|
local_config = File.join(root, 'config.rb')
|
||||||
if File.exists? local_config
|
if File.exists? local_config
|
||||||
logger.debug '== Reading: Local config'
|
logger.debug '== Reading: Local config'
|
||||||
instance_eval File.read(local_config), local_config, 1
|
config_context.instance_eval File.read(local_config), local_config, 1
|
||||||
end
|
end
|
||||||
|
|
||||||
run_hook :build_config if build?
|
if build?
|
||||||
run_hook :development_config if development?
|
run_hook :build_config
|
||||||
|
config_context.execute_configure_callbacks(:build)
|
||||||
|
end
|
||||||
|
|
||||||
|
if development?
|
||||||
|
run_hook :development_config
|
||||||
|
config_context.execute_configure_callbacks(:development)
|
||||||
|
end
|
||||||
|
|
||||||
run_hook :instance_available
|
run_hook :instance_available
|
||||||
|
|
||||||
|
@ -177,6 +184,7 @@ module Middleman
|
||||||
end
|
end
|
||||||
|
|
||||||
run_hook :after_configuration
|
run_hook :after_configuration
|
||||||
|
config_context.execute_after_configuration_callbacks
|
||||||
|
|
||||||
logger.debug 'Loaded extensions:'
|
logger.debug 'Loaded extensions:'
|
||||||
self.extensions.each do |ext, klass|
|
self.extensions.each do |ext, klass|
|
||||||
|
|
|
@ -51,6 +51,7 @@ module Middleman
|
||||||
@inst ||= begin
|
@inst ||= begin
|
||||||
mm = new(&block)
|
mm = new(&block)
|
||||||
mm.run_hook :ready
|
mm.run_hook :ready
|
||||||
|
mm.config_context.execute_ready_callbacks
|
||||||
mm
|
mm
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,69 +2,72 @@
|
||||||
module Middleman
|
module Middleman
|
||||||
module CoreExtensions
|
module CoreExtensions
|
||||||
module Routing
|
module Routing
|
||||||
# Takes a block which allows many pages to have the same layout
|
|
||||||
#
|
|
||||||
# with_layout :admin do
|
|
||||||
# page "/admin/"
|
|
||||||
# page "/admin/login.html"
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# @param [String, Symbol] layout_name
|
|
||||||
# @return [void]
|
|
||||||
def with_layout(layout_name, &block)
|
|
||||||
old_layout = config[:layout]
|
|
||||||
|
|
||||||
config[:layout] = layout_name
|
# Sandboxed layout to implement temporary overriding of layout.
|
||||||
instance_exec(&block) if block_given?
|
class LayoutBlock
|
||||||
ensure
|
attr_reader :scope
|
||||||
config[:layout] = old_layout
|
|
||||||
|
def initialize(scope, layout_name)
|
||||||
|
@scope = scope
|
||||||
|
@layout_name = layout_name
|
||||||
end
|
end
|
||||||
|
|
||||||
# The page method allows the layout to be set on a specific path
|
|
||||||
#
|
|
||||||
# page "/about.html", :layout => false
|
|
||||||
# page "/", :layout => :homepage_layout
|
|
||||||
#
|
|
||||||
# @param [String] url
|
|
||||||
# @param [Hash] opts
|
|
||||||
# @return [void]
|
|
||||||
def page(url, opts={}, &block)
|
def page(url, opts={}, &block)
|
||||||
blocks = Array(block)
|
opts[:layout] ||= @layout_name
|
||||||
|
@scope.page(url, opts, &block)
|
||||||
|
end
|
||||||
|
|
||||||
# Default layout
|
delegate :proxy, :to => :scope
|
||||||
opts[:layout] = config[:layout] if opts[:layout].nil?
|
end
|
||||||
|
|
||||||
# If the url is a regexp
|
# Takes a block which allows many pages to have the same layout
|
||||||
if url.is_a?(Regexp) || url.include?('*')
|
#
|
||||||
|
# with_layout :admin do
|
||||||
|
# page "/admin/"
|
||||||
|
# page "/admin/login.html"
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# @param [String, Symbol] layout_name
|
||||||
|
# @return [void]
|
||||||
|
def with_layout(layout_name, &block)
|
||||||
|
LayoutBlock.new(self, layout_name).instance_eval(&block)
|
||||||
|
end
|
||||||
|
|
||||||
# Use the metadata loop for matching against paths at runtime
|
# The page method allows the layout to be set on a specific path
|
||||||
sitemap.provides_metadata_for_path(url) do |_|
|
#
|
||||||
{ :options => opts, :blocks => blocks }
|
# page "/about.html", :layout => false
|
||||||
end
|
# page "/", :layout => :homepage_layout
|
||||||
|
#
|
||||||
return
|
# @param [String] url
|
||||||
end
|
# @param [Hash] opts
|
||||||
|
# @return [void]
|
||||||
|
def page(url, opts={}, &block)
|
||||||
|
# Default layout
|
||||||
|
opts[:layout] = @app.config[:layout] if opts[:layout].nil?
|
||||||
|
metadata = { :options => opts, :blocks => Array(block) }
|
||||||
|
|
||||||
|
# If the url is a regexp
|
||||||
|
unless url.is_a?(Regexp) || url.include?('*')
|
||||||
# Normalized path
|
# Normalized path
|
||||||
url = '/' + Middleman::Util.normalize_path(url)
|
url = '/' + Middleman::Util.normalize_path(url)
|
||||||
if url.end_with?('/') || File.directory?(File.join(source_dir, url))
|
if url.end_with?('/') || File.directory?(File.join(@app.source_dir, url))
|
||||||
url = File.join(url, config[:index_file])
|
url = File.join(url, @app.config[:index_file])
|
||||||
end
|
end
|
||||||
|
|
||||||
# Setup proxy
|
# Setup proxy
|
||||||
if target = opts.delete(:proxy)
|
if target = opts.delete(:proxy)
|
||||||
# TODO: deprecate proxy through page?
|
# TODO: deprecate proxy through page?
|
||||||
proxy(url, target, opts, &block) and return
|
@app.proxy(url, target, opts, &block)
|
||||||
|
return
|
||||||
elsif opts.delete(:ignore)
|
elsif opts.delete(:ignore)
|
||||||
# TODO: deprecate ignore through page?
|
# TODO: deprecate ignore through page?
|
||||||
ignore(url)
|
@app.ignore(url)
|
||||||
end
|
|
||||||
|
|
||||||
# Setup a metadata matcher for rendering those options
|
|
||||||
sitemap.provides_metadata_for_path(url) do |_|
|
|
||||||
{ :options => opts, :blocks => blocks }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Setup a metadata matcher for rendering those options
|
||||||
|
@app.sitemap.provides_metadata_for_path(url) { |_| metadata }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,8 +12,9 @@ module Middleman
|
||||||
|
|
||||||
# Once registered
|
# Once registered
|
||||||
def registered(app)
|
def registered(app)
|
||||||
# Default less options
|
# Default stylus options
|
||||||
app.set :styl, {}
|
app.config.define_setting :styl, {}, 'Stylus config options'
|
||||||
|
|
||||||
|
|
||||||
app.before_configuration do
|
app.before_configuration do
|
||||||
template_extensions :styl => :css
|
template_extensions :styl => :css
|
||||||
|
|
|
@ -1,12 +1,3 @@
|
||||||
require 'middleman-core/sitemap/store'
|
|
||||||
require 'middleman-core/sitemap/resource'
|
|
||||||
|
|
||||||
require 'middleman-core/sitemap/extensions/on_disk'
|
|
||||||
require 'middleman-core/sitemap/extensions/redirects'
|
|
||||||
require 'middleman-core/sitemap/extensions/request_endpoints'
|
|
||||||
require 'middleman-core/sitemap/extensions/proxies'
|
|
||||||
require 'middleman-core/sitemap/extensions/ignores'
|
|
||||||
|
|
||||||
# Core Sitemap Extensions
|
# Core Sitemap Extensions
|
||||||
module Middleman
|
module Middleman
|
||||||
|
|
||||||
|
@ -18,11 +9,6 @@ module Middleman
|
||||||
# Once registered
|
# Once registered
|
||||||
def registered(app)
|
def registered(app)
|
||||||
|
|
||||||
app.register Middleman::Sitemap::Extensions::RequestEndpoints
|
|
||||||
app.register Middleman::Sitemap::Extensions::Proxies
|
|
||||||
app.register Middleman::Sitemap::Extensions::Ignores
|
|
||||||
app.register Middleman::Sitemap::Extensions::Redirects
|
|
||||||
|
|
||||||
# Set to automatically convert some characters into a directory
|
# Set to automatically convert some characters into a directory
|
||||||
app.config.define_setting :automatic_directory_matcher, nil, 'Set to automatically convert some characters into a directory'
|
app.config.define_setting :automatic_directory_matcher, nil, 'Set to automatically convert some characters into a directory'
|
||||||
|
|
||||||
|
@ -46,11 +32,6 @@ module Middleman
|
||||||
|
|
||||||
# Include instance methods
|
# Include instance methods
|
||||||
app.send :include, InstanceMethods
|
app.send :include, InstanceMethods
|
||||||
|
|
||||||
# Initialize Sitemap
|
|
||||||
app.before_configuration do
|
|
||||||
sitemap
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
alias :included :registered
|
alias :included :registered
|
||||||
|
|
||||||
|
@ -59,12 +40,6 @@ module Middleman
|
||||||
# Sitemap instance methods
|
# Sitemap instance methods
|
||||||
module InstanceMethods
|
module InstanceMethods
|
||||||
|
|
||||||
# Get the sitemap class instance
|
|
||||||
# @return [Middleman::Sitemap::Store]
|
|
||||||
def sitemap
|
|
||||||
@_sitemap ||= Store.new(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Get the resource object for the current path
|
# Get the resource object for the current path
|
||||||
# @return [Middleman::Sitemap::Resource]
|
# @return [Middleman::Sitemap::Resource]
|
||||||
def current_page
|
def current_page
|
||||||
|
|
|
@ -4,87 +4,61 @@ module Middleman
|
||||||
|
|
||||||
module Extensions
|
module Extensions
|
||||||
|
|
||||||
module Ignores
|
# Class to handle managing ignores
|
||||||
|
class Ignores
|
||||||
|
def initialize(sitemap)
|
||||||
|
@app = sitemap.app
|
||||||
|
@app.add_to_config_context :ignore, &method(:create_ignore)
|
||||||
|
@app.define_singleton_method(:ignore, &method(:create_ignore))
|
||||||
|
|
||||||
# Setup extension
|
# Array of callbacks which can ass ignored
|
||||||
class << self
|
@ignored_callbacks = []
|
||||||
|
|
||||||
# Once registered
|
sitemap.define_singleton_method(:ignored?, &method(:ignored?))
|
||||||
def registered(app)
|
::Middleman::Sitemap::Resource.send :include, IgnoreResourceInstanceMethods
|
||||||
# Include methods
|
|
||||||
app.send :include, InstanceMethods
|
|
||||||
|
|
||||||
::Middleman::Sitemap::Resource.send :include, ResourceInstanceMethods
|
|
||||||
end
|
|
||||||
|
|
||||||
alias :included :registered
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Helpers methods for Resources
|
# Ignore a path or add an ignore callback
|
||||||
module ResourceInstanceMethods
|
# @param [String, Regexp] path Path glob expression, or path regex
|
||||||
|
# @return [void]
|
||||||
# Whether the Resource is ignored
|
def create_ignore(path=nil, &block)
|
||||||
# @return [Boolean]
|
if path.is_a? Regexp
|
||||||
def ignored?
|
@ignored_callbacks << Proc.new {|p| p =~ path }
|
||||||
@app.ignore_manager.ignored?(path) ||
|
elsif path.is_a? String
|
||||||
(!proxy? &&
|
|
||||||
@app.ignore_manager.ignored?(source_file.sub("#{@app.source_dir}/", ''))
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Ignore-related instance methods
|
|
||||||
module InstanceMethods
|
|
||||||
def ignore_manager
|
|
||||||
@_ignore_manager ||= IgnoreManager.new(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Ignore a path or add an ignore callback
|
|
||||||
# @param [String, Regexp] path Path glob expression, or path regex
|
|
||||||
# @return [void]
|
|
||||||
def ignore(path=nil, &block)
|
|
||||||
ignore_manager.ignore(path, &block)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Class to handle managing ignores
|
|
||||||
class IgnoreManager
|
|
||||||
def initialize(app)
|
|
||||||
@app = app
|
|
||||||
|
|
||||||
# Array of callbacks which can ass ignored
|
|
||||||
@ignored_callbacks = []
|
|
||||||
end
|
|
||||||
|
|
||||||
# Ignore a path or add an ignore callback
|
|
||||||
# @param [String, Regexp] path Path glob expression, or path regex
|
|
||||||
# @return [void]
|
|
||||||
def ignore(path=nil, &block)
|
|
||||||
if path.is_a? Regexp
|
|
||||||
@ignored_callbacks << Proc.new {|p| p =~ path }
|
|
||||||
elsif path.is_a? String
|
|
||||||
path_clean = ::Middleman::Util.normalize_path(path)
|
|
||||||
if path_clean.include?('*') # It's a glob
|
|
||||||
@ignored_callbacks << Proc.new {|p| File.fnmatch(path_clean, p) }
|
|
||||||
else
|
|
||||||
# Add a specific-path ignore unless that path is already covered
|
|
||||||
return if ignored?(path_clean)
|
|
||||||
@ignored_callbacks << Proc.new {|p| p == path_clean }
|
|
||||||
end
|
|
||||||
elsif block_given?
|
|
||||||
@ignored_callbacks << block
|
|
||||||
end
|
|
||||||
|
|
||||||
@app.sitemap.invalidate_resources_not_ignored_cache!
|
|
||||||
end
|
|
||||||
|
|
||||||
# Whether a path is ignored
|
|
||||||
# @param [String] path
|
|
||||||
# @return [Boolean]
|
|
||||||
def ignored?(path)
|
|
||||||
path_clean = ::Middleman::Util.normalize_path(path)
|
path_clean = ::Middleman::Util.normalize_path(path)
|
||||||
@ignored_callbacks.any? { |b| b.call(path_clean) }
|
if path_clean.include?('*') # It's a glob
|
||||||
|
@ignored_callbacks << Proc.new {|p| File.fnmatch(path_clean, p) }
|
||||||
|
else
|
||||||
|
# Add a specific-path ignore unless that path is already covered
|
||||||
|
return if ignored?(path_clean)
|
||||||
|
@ignored_callbacks << Proc.new {|p| p == path_clean }
|
||||||
|
end
|
||||||
|
elsif block_given?
|
||||||
|
@ignored_callbacks << block
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@app.sitemap.invalidate_resources_not_ignored_cache!
|
||||||
|
end
|
||||||
|
|
||||||
|
# Whether a path is ignored
|
||||||
|
# @param [String] path
|
||||||
|
# @return [Boolean]
|
||||||
|
def ignored?(path)
|
||||||
|
path_clean = ::Middleman::Util.normalize_path(path)
|
||||||
|
@ignored_callbacks.any? { |b| b.call(path_clean) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Helpers methods for Resources
|
||||||
|
module IgnoreResourceInstanceMethods
|
||||||
|
|
||||||
|
# Whether the Resource is ignored
|
||||||
|
# @return [Boolean]
|
||||||
|
def ignored?
|
||||||
|
@app.sitemap.ignored?(path) ||
|
||||||
|
(!proxy? &&
|
||||||
|
@app.sitemap.ignored?(source_file.sub("#{@app.source_dir}/", ''))
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,165 +4,143 @@ module Middleman
|
||||||
|
|
||||||
module Extensions
|
module Extensions
|
||||||
|
|
||||||
module Proxies
|
# Manages the list of proxy configurations and manipulates the sitemap
|
||||||
|
# to include new resources based on those configurations
|
||||||
|
class Proxies
|
||||||
|
def initialize(sitemap)
|
||||||
|
@app = sitemap.app
|
||||||
|
@app.add_to_config_context :proxy, &method(:create_proxy)
|
||||||
|
@app.define_singleton_method(:proxy, &method(:create_proxy))
|
||||||
|
|
||||||
# Setup extension
|
@proxy_configs = Set.new
|
||||||
class << self
|
|
||||||
|
|
||||||
# Once registered
|
::Middleman::Sitemap::Resource.send :include, ProxyResourceInstanceMethods
|
||||||
def registered(app)
|
|
||||||
::Middleman::Sitemap::Resource.send :include, ResourceInstanceMethods
|
|
||||||
|
|
||||||
# Include methods
|
|
||||||
app.send :include, InstanceMethods
|
|
||||||
end
|
|
||||||
|
|
||||||
alias :included :registered
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module ResourceInstanceMethods
|
# Setup a proxy from a path to a target
|
||||||
# Whether this page is a proxy
|
# @param [String] path
|
||||||
# @return [Boolean]
|
# @param [String] target
|
||||||
def proxy?
|
# @param [Hash] opts options to apply to the proxy, including things like
|
||||||
!!@proxied_to
|
# :locals, :ignore to hide the proxy target, :layout, and :directory_indexes.
|
||||||
|
# @return [void]
|
||||||
|
def create_proxy(path, target, opts={}, &block)
|
||||||
|
metadata = { :options => {}, :locals => {}, :blocks => [] }
|
||||||
|
metadata[:blocks] << block if block_given?
|
||||||
|
metadata[:locals] = opts.delete(:locals) || {}
|
||||||
|
|
||||||
|
@app.ignore(target) if opts.delete(:ignore)
|
||||||
|
metadata[:options] = opts
|
||||||
|
|
||||||
|
@proxy_configs << ProxyConfiguration.new(:path => path, :target => target, :metadata => metadata)
|
||||||
|
|
||||||
|
@app.sitemap.rebuild_resource_list!(:added_proxy)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Update the main sitemap resource list
|
||||||
|
# @return [void]
|
||||||
|
def manipulate_resource_list(resources)
|
||||||
|
resources + @proxy_configs.map do |config|
|
||||||
|
p = ::Middleman::Sitemap::Resource.new(
|
||||||
|
@app.sitemap,
|
||||||
|
config.path
|
||||||
|
)
|
||||||
|
p.proxy_to(config.target)
|
||||||
|
p.add_metadata(config.metadata)
|
||||||
|
p
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Set this page to proxy to a target path
|
# Configuration for a proxy instance
|
||||||
# @param [String] target
|
class ProxyConfiguration
|
||||||
# @return [void]
|
# The path that this proxy will appear at in the sitemap
|
||||||
def proxy_to(target)
|
attr_reader :path
|
||||||
target = ::Middleman::Util.normalize_path(target)
|
def path=(p)
|
||||||
raise "You can't proxy #{path} to itself!" if target == path
|
@path = ::Middleman::Util.normalize_path(p)
|
||||||
@proxied_to = target
|
end
|
||||||
end
|
|
||||||
|
|
||||||
# The path of the page this page is proxied to, or nil if it's not proxied.
|
# The existing sitemap path that this will proxy to
|
||||||
# @return [String]
|
attr_reader :target
|
||||||
def proxied_to
|
def target=(t)
|
||||||
@proxied_to
|
@target = ::Middleman::Util.normalize_path(t)
|
||||||
end
|
end
|
||||||
|
|
||||||
# The resource for the page this page is proxied to. Throws an exception
|
# Additional metadata like blocks and locals to apply to the proxy
|
||||||
# if there is no resource.
|
attr_accessor :metadata
|
||||||
# @return [Sitemap::Resource]
|
|
||||||
def proxied_to_resource
|
|
||||||
proxy_resource = store.find_resource_by_path(proxied_to)
|
|
||||||
|
|
||||||
unless proxy_resource
|
# Create a new proxy configuration from hash options
|
||||||
raise "Path #{path} proxies to unknown file #{proxied_to}:#{store.resources.map(&:path)}"
|
def initialize(options={})
|
||||||
end
|
options.each do |key, value|
|
||||||
|
send "#{key}=", value
|
||||||
if proxy_resource.proxy?
|
|
||||||
raise "You can't proxy #{path} to #{proxied_to} which is itself a proxy."
|
|
||||||
end
|
|
||||||
|
|
||||||
proxy_resource
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_source_file
|
|
||||||
if proxy?
|
|
||||||
proxied_to_resource.source_file
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def content_type
|
|
||||||
mime_type = super
|
|
||||||
return mime_type if mime_type
|
|
||||||
|
|
||||||
if proxy?
|
|
||||||
proxied_to_resource.content_type
|
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module InstanceMethods
|
# Two configurations are equal if they reference the same path
|
||||||
def proxy_manager
|
def eql?(other)
|
||||||
@_proxy_manager ||= ProxyManager.new(self)
|
other.path == path
|
||||||
|
end
|
||||||
|
|
||||||
|
# Two configurations are equal if they reference the same path
|
||||||
|
def hash
|
||||||
|
path.hash
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module ProxyResourceInstanceMethods
|
||||||
|
# Whether this page is a proxy
|
||||||
|
# @return [Boolean]
|
||||||
|
def proxy?
|
||||||
|
!!@proxied_to
|
||||||
|
end
|
||||||
|
|
||||||
|
# Set this page to proxy to a target path
|
||||||
|
# @param [String] target
|
||||||
|
# @return [void]
|
||||||
|
def proxy_to(target)
|
||||||
|
target = ::Middleman::Util.normalize_path(target)
|
||||||
|
raise "You can't proxy #{path} to itself!" if target == path
|
||||||
|
@proxied_to = target
|
||||||
|
end
|
||||||
|
|
||||||
|
# The path of the page this page is proxied to, or nil if it's not proxied.
|
||||||
|
# @return [String]
|
||||||
|
def proxied_to
|
||||||
|
@proxied_to
|
||||||
|
end
|
||||||
|
|
||||||
|
# The resource for the page this page is proxied to. Throws an exception
|
||||||
|
# if there is no resource.
|
||||||
|
# @return [Sitemap::Resource]
|
||||||
|
def proxied_to_resource
|
||||||
|
proxy_resource = store.find_resource_by_path(proxied_to)
|
||||||
|
|
||||||
|
unless proxy_resource
|
||||||
|
raise "Path #{path} proxies to unknown file #{proxied_to}:#{store.resources.map(&:path)}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def proxy(*args, &block)
|
if proxy_resource.proxy?
|
||||||
proxy_manager.proxy(*args, &block)
|
raise "You can't proxy #{path} to #{proxied_to} which is itself a proxy."
|
||||||
|
end
|
||||||
|
|
||||||
|
proxy_resource
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_source_file
|
||||||
|
if proxy?
|
||||||
|
proxied_to_resource.source_file
|
||||||
|
else
|
||||||
|
super
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Manages the list of proxy configurations and manipulates the sitemap
|
def content_type
|
||||||
# to include new resources based on those configurations
|
mime_type = super
|
||||||
class ProxyManager
|
return mime_type if mime_type
|
||||||
def initialize(app)
|
|
||||||
@app = app
|
|
||||||
@proxy_configs = Set.new
|
|
||||||
end
|
|
||||||
|
|
||||||
# Setup a proxy from a path to a target
|
if proxy?
|
||||||
# @param [String] path
|
proxied_to_resource.content_type
|
||||||
# @param [String] target
|
else
|
||||||
# @param [Hash] opts options to apply to the proxy, including things like
|
nil
|
||||||
# :locals, :ignore to hide the proxy target, :layout, and :directory_indexes.
|
|
||||||
# @return [void]
|
|
||||||
def proxy(path, target, opts={}, &block)
|
|
||||||
metadata = { :options => {}, :locals => {}, :blocks => [] }
|
|
||||||
metadata[:blocks] << block if block_given?
|
|
||||||
metadata[:locals] = opts.delete(:locals) || {}
|
|
||||||
|
|
||||||
@app.ignore(target) if opts.delete(:ignore)
|
|
||||||
metadata[:options] = opts
|
|
||||||
|
|
||||||
@proxy_configs << ProxyConfiguration.new(:path => path, :target => target, :metadata => metadata)
|
|
||||||
|
|
||||||
@app.sitemap.rebuild_resource_list!(:added_proxy)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Update the main sitemap resource list
|
|
||||||
# @return [void]
|
|
||||||
def manipulate_resource_list(resources)
|
|
||||||
resources + @proxy_configs.map do |config|
|
|
||||||
p = ::Middleman::Sitemap::Resource.new(
|
|
||||||
@app.sitemap,
|
|
||||||
config.path
|
|
||||||
)
|
|
||||||
p.proxy_to(config.target)
|
|
||||||
p.add_metadata(config.metadata)
|
|
||||||
p
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Configuration for a proxy instance
|
|
||||||
class ProxyConfiguration
|
|
||||||
# The path that this proxy will appear at in the sitemap
|
|
||||||
attr_reader :path
|
|
||||||
def path=(p)
|
|
||||||
@path = ::Middleman::Util.normalize_path(p)
|
|
||||||
end
|
|
||||||
|
|
||||||
# The existing sitemap path that this will proxy to
|
|
||||||
attr_reader :target
|
|
||||||
def target=(t)
|
|
||||||
@target = ::Middleman::Util.normalize_path(t)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Additional metadata like blocks and locals to apply to the proxy
|
|
||||||
attr_accessor :metadata
|
|
||||||
|
|
||||||
# Create a new proxy configuration from hash options
|
|
||||||
def initialize(options={})
|
|
||||||
options.each do |key, value|
|
|
||||||
send "#{key}=", value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Two configurations are equal if they reference the same path
|
|
||||||
def eql?(other)
|
|
||||||
other.path == path
|
|
||||||
end
|
|
||||||
|
|
||||||
# Two configurations are equal if they reference the same path
|
|
||||||
def hash
|
|
||||||
path.hash
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,126 +1,105 @@
|
||||||
|
require 'middleman-core/sitemap/resource'
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
|
|
||||||
module Sitemap
|
module Sitemap
|
||||||
|
|
||||||
module Extensions
|
module Extensions
|
||||||
|
|
||||||
module Redirects
|
# Manages the list of proxy configurations and manipulates the sitemap
|
||||||
|
# to include new resources based on those configurations
|
||||||
|
class Redirects
|
||||||
|
def initialize(sitemap)
|
||||||
|
@app = sitemap.app
|
||||||
|
@app.add_to_config_context :redirect, &method(:create_redirect)
|
||||||
|
|
||||||
# Setup extension
|
@redirects = {}
|
||||||
class << self
|
|
||||||
|
|
||||||
# Once registered
|
|
||||||
def registered(app)
|
|
||||||
# Include methods
|
|
||||||
app.send :include, InstanceMethods
|
|
||||||
end
|
|
||||||
|
|
||||||
alias :included :registered
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module InstanceMethods
|
# Setup a redirect from a path to a target
|
||||||
def redirect_manager
|
# @param [String] path
|
||||||
@_redirect_manager ||= RedirectManager.new(self)
|
# @param [Hash] opts The :to value gives a target path
|
||||||
|
def create_redirect(path, opts={}, &block)
|
||||||
|
if block_given?
|
||||||
|
opts[:template] = block
|
||||||
end
|
end
|
||||||
|
|
||||||
def redirect(*args, &block)
|
@redirects[path] = opts
|
||||||
redirect_manager.create_redirect(*args, &block)
|
|
||||||
|
@app.sitemap.rebuild_resource_list!(:added_redirect)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Update the main sitemap resource list
|
||||||
|
# @return [void]
|
||||||
|
def manipulate_resource_list(resources)
|
||||||
|
resources + @redirects.map do |path, opts|
|
||||||
|
r = RedirectResource.new(
|
||||||
|
@app.sitemap,
|
||||||
|
path,
|
||||||
|
opts[:to]
|
||||||
|
)
|
||||||
|
r.output = opts[:template] if opts[:template]
|
||||||
|
r
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class RedirectResource < ::Middleman::Sitemap::Resource
|
||||||
|
attr_accessor :output
|
||||||
|
|
||||||
|
def initialize(store, path, target)
|
||||||
|
@request_path = target
|
||||||
|
|
||||||
|
super(store, path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def template?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(*args, &block)
|
||||||
|
url = ::Middleman::Util.url_for(store.app, @request_path, {
|
||||||
|
:relative => false,
|
||||||
|
:find_resource => true
|
||||||
|
})
|
||||||
|
|
||||||
|
if output
|
||||||
|
output.call(path, url)
|
||||||
|
else
|
||||||
|
<<-END
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv=refresh content="0; url=#{url}" />
|
||||||
|
<meta name="robots" content="noindex,follow" />
|
||||||
|
<meta http-equiv="cache-control" content="no-cache" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
END
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Manages the list of proxy configurations and manipulates the sitemap
|
# def request_path
|
||||||
# to include new resources based on those configurations
|
# @request_path
|
||||||
class RedirectManager
|
# end
|
||||||
def initialize(app)
|
|
||||||
@app = app
|
|
||||||
@redirects = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
# Setup a redirect from a path to a target
|
def binary?
|
||||||
# @param [String] path
|
false
|
||||||
# @param [Hash] opts The :to value gives a target path
|
|
||||||
def create_redirect(path, opts={}, &block)
|
|
||||||
if block_given?
|
|
||||||
opts[:template] = block
|
|
||||||
end
|
|
||||||
|
|
||||||
@redirects[path] = opts
|
|
||||||
|
|
||||||
@app.sitemap.rebuild_resource_list!(:added_redirect)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Update the main sitemap resource list
|
|
||||||
# @return [void]
|
|
||||||
def manipulate_resource_list(resources)
|
|
||||||
resources + @redirects.map do |path, opts|
|
|
||||||
r = RedirectResource.new(
|
|
||||||
@app.sitemap,
|
|
||||||
path,
|
|
||||||
opts[:to]
|
|
||||||
)
|
|
||||||
r.output = opts[:template] if opts[:template]
|
|
||||||
r
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class RedirectResource < ::Middleman::Sitemap::Resource
|
def raw_data
|
||||||
attr_accessor :output
|
{}
|
||||||
|
|
||||||
def initialize(store, path, target)
|
|
||||||
@request_path = target
|
|
||||||
|
|
||||||
super(store, path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def template?
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
def render(*args, &block)
|
|
||||||
url = ::Middleman::Util.url_for(store.app, @request_path, {
|
|
||||||
:relative => false,
|
|
||||||
:find_resource => true
|
|
||||||
})
|
|
||||||
|
|
||||||
if output
|
|
||||||
output.call(path, url)
|
|
||||||
else
|
|
||||||
<<-END
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv=refresh content="0; url=#{url}" />
|
|
||||||
<meta name="robots" content="noindex,follow" />
|
|
||||||
<meta http-equiv="cache-control" content="no-cache" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
END
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# def request_path
|
|
||||||
# @request_path
|
|
||||||
# end
|
|
||||||
|
|
||||||
def binary?
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
def raw_data
|
|
||||||
{}
|
|
||||||
end
|
|
||||||
|
|
||||||
def ignored?
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
def metadata
|
|
||||||
@local_metadata.dup
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ignored?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def metadata
|
||||||
|
@local_metadata.dup
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,110 +4,87 @@ module Middleman
|
||||||
|
|
||||||
module Extensions
|
module Extensions
|
||||||
|
|
||||||
module RequestEndpoints
|
class RequestEndpoints
|
||||||
|
|
||||||
# Setup extension
|
|
||||||
class << self
|
|
||||||
|
|
||||||
# Once registered
|
|
||||||
def registered(app)
|
|
||||||
# Include methods
|
|
||||||
app.send :include, InstanceMethods
|
|
||||||
end
|
|
||||||
|
|
||||||
alias :included :registered
|
|
||||||
end
|
|
||||||
|
|
||||||
module InstanceMethods
|
|
||||||
def endpoint_manager
|
|
||||||
@_endpoint_manager ||= EndpointManager.new(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
def endpoint(*args, &block)
|
|
||||||
endpoint_manager.create_endpoint(*args, &block)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Manages the list of proxy configurations and manipulates the sitemap
|
# Manages the list of proxy configurations and manipulates the sitemap
|
||||||
# to include new resources based on those configurations
|
# to include new resources based on those configurations
|
||||||
class EndpointManager
|
def initialize(sitemap)
|
||||||
def initialize(app)
|
@app = sitemap.app
|
||||||
@app = app
|
@app.add_to_config_context :endpoint, &method(:create_endpoint)
|
||||||
@endpoints = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
# Setup a proxy from a path to a target
|
@endpoints = {}
|
||||||
# @param [String] path
|
|
||||||
# @param [Hash] opts The :path value gives a request path if it
|
|
||||||
# differs from the output path
|
|
||||||
def create_endpoint(path, opts={}, &block)
|
|
||||||
endpoint = {
|
|
||||||
:request_path => path
|
|
||||||
}
|
|
||||||
|
|
||||||
if block_given?
|
|
||||||
endpoint[:output] = block
|
|
||||||
else
|
|
||||||
endpoint[:request_path] = opts[:path] if opts.has_key?(:path)
|
|
||||||
end
|
|
||||||
|
|
||||||
@endpoints[path] = endpoint
|
|
||||||
|
|
||||||
@app.sitemap.rebuild_resource_list!(:added_endpoint)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Update the main sitemap resource list
|
|
||||||
# @return [void]
|
|
||||||
def manipulate_resource_list(resources)
|
|
||||||
resources + @endpoints.map do |path, config|
|
|
||||||
r = EndpointResource.new(
|
|
||||||
@app.sitemap,
|
|
||||||
path,
|
|
||||||
config[:request_path]
|
|
||||||
)
|
|
||||||
r.output = config[:output] if config.has_key?(:output)
|
|
||||||
r
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class EndpointResource < ::Middleman::Sitemap::Resource
|
# Setup a proxy from a path to a target
|
||||||
attr_accessor :output
|
# @param [String] path
|
||||||
|
# @param [Hash] opts The :path value gives a request path if it
|
||||||
|
# differs from the output path
|
||||||
|
def create_endpoint(path, opts={}, &block)
|
||||||
|
endpoint = {
|
||||||
|
:request_path => path
|
||||||
|
}
|
||||||
|
|
||||||
def initialize(store, path, source_file)
|
if block_given?
|
||||||
@request_path = ::Middleman::Util.normalize_path(source_file)
|
endpoint[:output] = block
|
||||||
|
else
|
||||||
super(store, path)
|
endpoint[:request_path] = opts[:path] if opts.has_key?(:path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def template?
|
@endpoints[path] = endpoint
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
def render(*args, &block)
|
@app.sitemap.rebuild_resource_list!(:added_endpoint)
|
||||||
return self.output.call if self.output
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def request_path
|
# Update the main sitemap resource list
|
||||||
@request_path
|
# @return [void]
|
||||||
|
def manipulate_resource_list(resources)
|
||||||
|
resources + @endpoints.map do |path, config|
|
||||||
|
r = EndpointResource.new(
|
||||||
|
@app.sitemap,
|
||||||
|
path,
|
||||||
|
config[:request_path]
|
||||||
|
)
|
||||||
|
r.output = config[:output] if config.has_key?(:output)
|
||||||
|
r
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def binary?
|
class EndpointResource < ::Middleman::Sitemap::Resource
|
||||||
false
|
attr_accessor :output
|
||||||
end
|
|
||||||
|
|
||||||
def raw_data
|
def initialize(store, path, source_file)
|
||||||
{}
|
@request_path = ::Middleman::Util.normalize_path(source_file)
|
||||||
end
|
|
||||||
|
|
||||||
def ignored?
|
super(store, path)
|
||||||
false
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def metadata
|
def template?
|
||||||
@local_metadata.dup
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render(*args, &block)
|
||||||
|
return self.output.call if self.output
|
||||||
|
end
|
||||||
|
|
||||||
|
def request_path
|
||||||
|
@request_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def binary?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def raw_data
|
||||||
|
{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def ignored?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def metadata
|
||||||
|
@local_metadata.dup
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,12 +9,12 @@ module Middleman
|
||||||
# @return [Middleman::Sitemap::Resource, nil]
|
# @return [Middleman::Sitemap::Resource, nil]
|
||||||
def parent
|
def parent
|
||||||
parts = path.split('/')
|
parts = path.split('/')
|
||||||
parts.pop if path.include?(app.index_file)
|
parts.pop if path.include?(app.config[:index_file])
|
||||||
|
|
||||||
return nil if parts.length < 1
|
return nil if parts.length < 1
|
||||||
|
|
||||||
parts.pop
|
parts.pop
|
||||||
parts << app.index_file
|
parts << app.config[:index_file]
|
||||||
|
|
||||||
parent_path = '/' + parts.join('/')
|
parent_path = '/' + parts.join('/')
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ module Middleman
|
||||||
base_path = eponymous_directory_path
|
base_path = eponymous_directory_path
|
||||||
prefix = %r|^#{base_path.sub("/", "\\/")}|
|
prefix = %r|^#{base_path.sub("/", "\\/")}|
|
||||||
else
|
else
|
||||||
base_path = path.sub("#{app.index_file}", '')
|
base_path = path.sub("#{app.config[:index_file]}", '')
|
||||||
prefix = %r|^#{base_path.sub("/", "\\/")}|
|
prefix = %r|^#{base_path.sub("/", "\\/")}|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ module Middleman
|
||||||
if parts.length == 1
|
if parts.length == 1
|
||||||
true
|
true
|
||||||
elsif parts.length == 2
|
elsif parts.length == 2
|
||||||
parts.last == app.index_file
|
parts.last == app.config[:index_file]
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
@ -61,14 +61,14 @@ module Middleman
|
||||||
# Whether this resource either a directory index, or has the same name as an existing directory in the source
|
# Whether this resource either a directory index, or has the same name as an existing directory in the source
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
def directory_index?
|
def directory_index?
|
||||||
path.include?(app.index_file) || path =~ /\/$/ || eponymous_directory?
|
path.include?(app.config[:index_file]) || path =~ /\/$/ || eponymous_directory?
|
||||||
end
|
end
|
||||||
|
|
||||||
# Whether the resource has the same name as a directory in the source
|
# Whether the resource has the same name as a directory in the source
|
||||||
# (e.g., if the resource is named 'gallery.html' and a path exists named 'gallery/', this would return true)
|
# (e.g., if the resource is named 'gallery.html' and a path exists named 'gallery/', this would return true)
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
def eponymous_directory?
|
def eponymous_directory?
|
||||||
if !path.end_with?("/#{app.index_file}") && destination_path.end_with?("/#{app.index_file}")
|
if !path.end_with?("/#{app.config[:index_file]}") && destination_path.end_with?("/#{app.config[:index_file]}")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
full_path = File.join(app.source_dir, eponymous_directory_path)
|
full_path = File.join(app.source_dir, eponymous_directory_path)
|
||||||
|
|
|
@ -149,11 +149,11 @@ module Middleman
|
||||||
# @return [String]
|
# @return [String]
|
||||||
def url
|
def url
|
||||||
url_path = destination_path
|
url_path = destination_path
|
||||||
if app.strip_index_file
|
if app.config[:strip_index_file]
|
||||||
url_path = url_path.sub(/(^|\/)#{Regexp.escape(app.index_file)}$/,
|
url_path = url_path.sub(/(^|\/)#{Regexp.escape(app.config[:index_file])}$/,
|
||||||
app.trailing_slash ? '/' : '')
|
app.config[:trailing_slash] ? '/' : '')
|
||||||
end
|
end
|
||||||
File.join(app.respond_to?(:http_prefix) ? app.http_prefix : '/', url_path)
|
File.join(app.config[:http_prefix], url_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Whether the source file is binary.
|
# Whether the source file is binary.
|
||||||
|
|
|
@ -3,6 +3,13 @@ require 'active_support/core_ext/hash/deep_merge'
|
||||||
require 'monitor'
|
require 'monitor'
|
||||||
require 'middleman-core/sitemap/queryable'
|
require 'middleman-core/sitemap/queryable'
|
||||||
|
|
||||||
|
# Extensions
|
||||||
|
require 'middleman-core/sitemap/extensions/on_disk'
|
||||||
|
require 'middleman-core/sitemap/extensions/redirects'
|
||||||
|
require 'middleman-core/sitemap/extensions/request_endpoints'
|
||||||
|
require 'middleman-core/sitemap/extensions/proxies'
|
||||||
|
require 'middleman-core/sitemap/extensions/ignores'
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
|
|
||||||
# Sitemap namespace
|
# Sitemap namespace
|
||||||
|
@ -29,21 +36,31 @@ module Middleman
|
||||||
@_cached_metadata = {}
|
@_cached_metadata = {}
|
||||||
@resource_list_manipulators = []
|
@resource_list_manipulators = []
|
||||||
@needs_sitemap_rebuild = true
|
@needs_sitemap_rebuild = true
|
||||||
|
|
||||||
@lock = Monitor.new
|
@lock = Monitor.new
|
||||||
|
|
||||||
reset_lookup_cache!
|
reset_lookup_cache!
|
||||||
|
|
||||||
# Register classes which can manipulate the main site map list
|
# Handle ignore commands
|
||||||
register_resource_list_manipulator(:on_disk, Middleman::Sitemap::Extensions::OnDisk.new(self))
|
Middleman::Sitemap::Extensions::Ignores.new(self)
|
||||||
|
|
||||||
# Request Endpoints
|
# Extensions
|
||||||
register_resource_list_manipulator(:request_endpoints, @app.endpoint_manager)
|
{
|
||||||
|
# Register classes which can manipulate the main site map list
|
||||||
|
on_disk: Middleman::Sitemap::Extensions::OnDisk,
|
||||||
|
|
||||||
# Proxies
|
# Request Endpoints
|
||||||
register_resource_list_manipulator(:proxies, @app.proxy_manager)
|
request_endpoints: Middleman::Sitemap::Extensions::RequestEndpoints,
|
||||||
|
|
||||||
# Redirects
|
# Proxies
|
||||||
register_resource_list_manipulator(:redirects, @app.redirect_manager)
|
proxies: Middleman::Sitemap::Extensions::Proxies,
|
||||||
|
|
||||||
|
# Redirects
|
||||||
|
redirects: Middleman::Sitemap::Extensions::Redirects
|
||||||
|
}.each do |k, m|
|
||||||
|
register_resource_list_manipulator(k, m.new(self))
|
||||||
|
end
|
||||||
|
|
||||||
|
app.config_context.class.send :delegate, :sitemap, :to => :app
|
||||||
end
|
end
|
||||||
|
|
||||||
# Register a klass which can manipulate the main site map list. Best to register
|
# Register a klass which can manipulate the main site map list. Best to register
|
||||||
|
|
|
@ -24,7 +24,9 @@ end
|
||||||
|
|
||||||
Given /^"([^\"]*)" is set to "([^\"]*)"$/ do |variable, value|
|
Given /^"([^\"]*)" is set to "([^\"]*)"$/ do |variable, value|
|
||||||
@initialize_commands ||= []
|
@initialize_commands ||= []
|
||||||
@initialize_commands << lambda { set(variable.to_sym, value) }
|
@initialize_commands << lambda {
|
||||||
|
config[variable.to_sym] = value
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
Given /^current environment is "([^\"]*)"$/ do |env|
|
Given /^current environment is "([^\"]*)"$/ do |env|
|
||||||
|
@ -44,8 +46,8 @@ Given /^the Server is running$/ do
|
||||||
|
|
||||||
initialize_commands = @initialize_commands || []
|
initialize_commands = @initialize_commands || []
|
||||||
initialize_commands.unshift lambda {
|
initialize_commands.unshift lambda {
|
||||||
set :environment, @current_env || :development
|
config[:environment] = @current_env || :development
|
||||||
set :show_exceptions, false
|
config[:show_exceptions] = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@server_inst = Middleman::Application.server.inst do
|
@server_inst = Middleman::Application.server.inst do
|
||||||
|
|
|
@ -105,8 +105,8 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension
|
||||||
def auto_tag(asset_ext, asset_dir=nil)
|
def auto_tag(asset_ext, asset_dir=nil)
|
||||||
if asset_dir.nil?
|
if asset_dir.nil?
|
||||||
asset_dir = case asset_ext
|
asset_dir = case asset_ext
|
||||||
when :js then js_dir
|
when :js then config[:js_dir]
|
||||||
when :css then css_dir
|
when :css then config[:css_dir]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -153,10 +153,10 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension
|
||||||
def asset_path(kind, source)
|
def asset_path(kind, source)
|
||||||
return source if source.to_s.include?('//') || source.to_s.start_with?('data:')
|
return source if source.to_s.include?('//') || source.to_s.start_with?('data:')
|
||||||
asset_folder = case kind
|
asset_folder = case kind
|
||||||
when :css then css_dir
|
when :css then config[:css_dir]
|
||||||
when :js then js_dir
|
when :js then config[:js_dir]
|
||||||
when :images then images_dir
|
when :images then config[:images_dir]
|
||||||
when :fonts then fonts_dir
|
when :fonts then config[:fonts_dir]
|
||||||
else kind.to_s
|
else kind.to_s
|
||||||
end
|
end
|
||||||
source = source.to_s.tr(' ', '')
|
source = source.to_s.tr(' ', '')
|
||||||
|
|
|
@ -20,7 +20,7 @@ class Middleman::Extensions::AutomaticImageSizes < ::Middleman::Extension
|
||||||
params[:alt] ||= ''
|
params[:alt] ||= ''
|
||||||
|
|
||||||
real_path = path
|
real_path = path
|
||||||
real_path = File.join(images_dir, real_path) unless real_path.start_with?('/')
|
real_path = File.join(config[:images_dir], real_path) unless real_path.start_with?('/')
|
||||||
full_path = File.join(source_dir, real_path)
|
full_path = File.join(source_dir, real_path)
|
||||||
|
|
||||||
if File.exists?(full_path)
|
if File.exists?(full_path)
|
||||||
|
|
|
@ -8,7 +8,7 @@ class Middleman::Extensions::CacheBuster < ::Middleman::Extension
|
||||||
app.compass_config do |config|
|
app.compass_config do |config|
|
||||||
config.asset_cache_buster do |path, real_path|
|
config.asset_cache_buster do |path, real_path|
|
||||||
real_path = real_path.path if real_path.is_a? File
|
real_path = real_path.path if real_path.is_a? File
|
||||||
real_path = real_path.gsub(File.join(root, build_dir), source)
|
real_path = real_path.gsub(File.join(app.root, app.config[:build_dir]), app.config[:source])
|
||||||
if File.readable?(real_path)
|
if File.readable?(real_path)
|
||||||
File.mtime(real_path).strftime('%s')
|
File.mtime(real_path).strftime('%s')
|
||||||
else
|
else
|
||||||
|
@ -35,7 +35,7 @@ class Middleman::Extensions::CacheBuster < ::Middleman::Extension
|
||||||
real_path_static = File.join(prefix, path)
|
real_path_static = File.join(prefix, path)
|
||||||
|
|
||||||
if build?
|
if build?
|
||||||
real_path_dynamic = File.join(build_dir, prefix, path)
|
real_path_dynamic = File.join(config[:build_dir], prefix, path)
|
||||||
real_path_dynamic = File.expand_path(real_path_dynamic, root)
|
real_path_dynamic = File.expand_path(real_path_dynamic, root)
|
||||||
http_path << '?' + File.mtime(real_path_dynamic).strftime('%s') if File.readable?(real_path_dynamic)
|
http_path << '?' + File.mtime(real_path_dynamic).strftime('%s') if File.readable?(real_path_dynamic)
|
||||||
elsif resource = sitemap.find_resource_by_path(real_path_static)
|
elsif resource = sitemap.find_resource_by_path(real_path_static)
|
||||||
|
|
|
@ -3,7 +3,7 @@ class Middleman::Extensions::DirectoryIndexes < ::Middleman::Extension
|
||||||
# Update the main sitemap resource list
|
# Update the main sitemap resource list
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def manipulate_resource_list(resources)
|
def manipulate_resource_list(resources)
|
||||||
index_file = app.index_file
|
index_file = app.config[:index_file]
|
||||||
new_index_path = "/#{index_file}"
|
new_index_path = "/#{index_file}"
|
||||||
|
|
||||||
resources.each do |resource|
|
resources.each do |resource|
|
||||||
|
|
|
@ -23,7 +23,7 @@ class Middleman::Extensions::Gzip < ::Middleman::Extension
|
||||||
|
|
||||||
def after_build(builder)
|
def after_build(builder)
|
||||||
num_threads = 4
|
num_threads = 4
|
||||||
paths = ::Middleman::Util.all_files_under(app.build_dir)
|
paths = ::Middleman::Util.all_files_under(app.config[:build_dir])
|
||||||
total_savings = 0
|
total_savings = 0
|
||||||
|
|
||||||
# Fill a queue with inputs
|
# Fill a queue with inputs
|
||||||
|
|
Loading…
Reference in a new issue