Merge pull request #1288 from bhollis/data
@bhollis metadata rewrite/refactor
This commit is contained in:
commit
e7108a5656
|
@ -2,13 +2,21 @@ Feature: Custom layouts
|
||||||
In order easily switch between relative and absolute paths
|
In order easily switch between relative and absolute paths
|
||||||
|
|
||||||
Scenario: Using custom :layout attribute
|
Scenario: Using custom :layout attribute
|
||||||
Given page "/custom-layout.html" has layout "custom"
|
Given a fixture app "custom-layout-app2"
|
||||||
|
And a file named "config.rb" with:
|
||||||
|
"""
|
||||||
|
page '/custom-layout.html', layout: :custom
|
||||||
|
"""
|
||||||
And the Server is running at "custom-layout-app2"
|
And the Server is running at "custom-layout-app2"
|
||||||
When I go to "/custom-layout.html"
|
When I go to "/custom-layout.html"
|
||||||
Then I should see "Custom Layout"
|
Then I should see "Custom Layout"
|
||||||
|
|
||||||
Scenario: Using custom :layout attribute with folders
|
Scenario: Using custom :layout attribute with folders
|
||||||
Given page "/custom-layout-dir/" has layout "custom"
|
Given a fixture app "custom-layout-app2"
|
||||||
|
And a file named "config.rb" with:
|
||||||
|
"""
|
||||||
|
page '/custom-layout-dir/', layout: :custom
|
||||||
|
"""
|
||||||
And the Server is running at "custom-layout-app2"
|
And the Server is running at "custom-layout-app2"
|
||||||
When I go to "/custom-layout-dir"
|
When I go to "/custom-layout-dir"
|
||||||
Then I should see "Custom Layout"
|
Then I should see "Custom Layout"
|
||||||
|
@ -18,7 +26,11 @@ Feature: Custom layouts
|
||||||
Then I should see "Custom Layout"
|
Then I should see "Custom Layout"
|
||||||
|
|
||||||
Scenario: Using custom :layout attribute with folders
|
Scenario: Using custom :layout attribute with folders
|
||||||
Given page "/custom-layout-dir" has layout "custom"
|
Given a fixture app "custom-layout-app2"
|
||||||
|
And a file named "config.rb" with:
|
||||||
|
"""
|
||||||
|
page '/custom-layout-dir', layout: :custom
|
||||||
|
"""
|
||||||
And the Server is running at "custom-layout-app2"
|
And the Server is running at "custom-layout-app2"
|
||||||
When I go to "/custom-layout-dir"
|
When I go to "/custom-layout-dir"
|
||||||
Then I should see "Custom Layout"
|
Then I should see "Custom Layout"
|
||||||
|
@ -28,7 +40,11 @@ Feature: Custom layouts
|
||||||
Then I should see "Custom Layout"
|
Then I should see "Custom Layout"
|
||||||
|
|
||||||
Scenario: Using custom :layout attribute with folders
|
Scenario: Using custom :layout attribute with folders
|
||||||
Given page "/custom-layout-dir/index.html" has layout "custom"
|
Given a fixture app "custom-layout-app2"
|
||||||
|
And a file named "config.rb" with:
|
||||||
|
"""
|
||||||
|
page '/custom-layout-dir/index.html', layout: :custom
|
||||||
|
"""
|
||||||
And the Server is running at "custom-layout-app2"
|
And the Server is running at "custom-layout-app2"
|
||||||
When I go to "/custom-layout-dir"
|
When I go to "/custom-layout-dir"
|
||||||
Then I should see "Custom Layout"
|
Then I should see "Custom Layout"
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
Given /^page "([^\"]*)" has layout "([^\"]*)"$/ do |url, layout|
|
|
||||||
@initialize_commands ||= []
|
|
||||||
@initialize_commands << lambda {
|
|
||||||
page(url, layout: layout.to_sym)
|
|
||||||
}
|
|
||||||
end
|
|
|
@ -1,10 +1,5 @@
|
||||||
require 'middleman-core/core_extensions/routing'
|
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
class ConfigContext
|
class ConfigContext
|
||||||
# page routing
|
|
||||||
include Middleman::CoreExtensions::Routing
|
|
||||||
|
|
||||||
attr_reader :app
|
attr_reader :app
|
||||||
|
|
||||||
# Whitelist methods that can reach out.
|
# Whitelist methods that can reach out.
|
||||||
|
|
|
@ -45,6 +45,11 @@ Middleman::Extensions.register :lorem, auto_activate: :before_configuration do
|
||||||
Middleman::Extensions::Lorem
|
Middleman::Extensions::Lorem
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Middleman::Extensions.register :routing, auto_activate: :before_configuration do
|
||||||
|
require 'middleman-core/core_extensions/routing'
|
||||||
|
Middleman::CoreExtensions::Routing
|
||||||
|
end
|
||||||
|
|
||||||
###
|
###
|
||||||
# Setup Optional Extensions
|
# Setup Optional Extensions
|
||||||
###
|
###
|
||||||
|
|
|
@ -83,9 +83,6 @@ module Middleman
|
||||||
# Search the root of the project for required files
|
# Search the root of the project for required files
|
||||||
$LOAD_PATH.unshift(root) unless $LOAD_PATH.include?(root)
|
$LOAD_PATH.unshift(root) unless $LOAD_PATH.include?(root)
|
||||||
|
|
||||||
# Evaluate a passed block if given
|
|
||||||
config_context.instance_exec(&block) if block_given?
|
|
||||||
|
|
||||||
super
|
super
|
||||||
|
|
||||||
::Middleman::Extension.clear_after_extension_callbacks
|
::Middleman::Extension.clear_after_extension_callbacks
|
||||||
|
@ -105,6 +102,9 @@ module Middleman
|
||||||
|
|
||||||
run_hook :before_configuration
|
run_hook :before_configuration
|
||||||
|
|
||||||
|
# Evaluate a passed block if given
|
||||||
|
config_context.instance_exec(&block) if block_given?
|
||||||
|
|
||||||
# Check for and evaluate local configuration in `config.rb`
|
# Check for and evaluate local configuration in `config.rb`
|
||||||
local_config = File.join(root, 'config.rb')
|
local_config = File.join(root, 'config.rb')
|
||||||
if File.exist? local_config
|
if File.exist? local_config
|
||||||
|
|
|
@ -10,6 +10,9 @@ require 'active_support/json'
|
||||||
# Extensions namespace
|
# Extensions namespace
|
||||||
module Middleman::CoreExtensions
|
module Middleman::CoreExtensions
|
||||||
class FrontMatter < ::Middleman::Extension
|
class FrontMatter < ::Middleman::Extension
|
||||||
|
# Try to run after routing but before directory_indexes
|
||||||
|
self.resource_list_manipulator_priority = 90
|
||||||
|
|
||||||
YAML_ERRORS = [StandardError]
|
YAML_ERRORS = [StandardError]
|
||||||
|
|
||||||
# https://github.com/tenderlove/psych/issues/23
|
# https://github.com/tenderlove/psych/issues/23
|
||||||
|
@ -29,61 +32,34 @@ module Middleman::CoreExtensions
|
||||||
app.files.deleted { |file| ext.clear_data(file) }
|
app.files.deleted { |file| ext.clear_data(file) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Modify each resource to add data & options from frontmatter.
|
||||||
|
def manipulate_resource_list(resources)
|
||||||
|
resources.each do |resource|
|
||||||
|
next if resource.source_file.blank?
|
||||||
|
|
||||||
|
fmdata = data(resource.source_file).first.dup
|
||||||
|
|
||||||
|
# Copy over special options
|
||||||
|
# TODO: Should we make people put these under "options" instead of having
|
||||||
|
# special known keys?
|
||||||
|
opts = fmdata.extract!(:layout, :layout_engine, :renderer_options, :directory_index, :content_type)
|
||||||
|
opts[:renderer_options].symbolize_keys! if opts.key?(:renderer_options)
|
||||||
|
|
||||||
|
ignored = fmdata.delete(:ignored)
|
||||||
|
|
||||||
|
# TODO: Enhance data? NOOOO
|
||||||
|
# TODO: stringify-keys? immutable/freeze?
|
||||||
|
|
||||||
|
resource.add_metadata options: opts, page: fmdata
|
||||||
|
|
||||||
|
resource.ignore! if ignored == true && !resource.proxy?
|
||||||
|
|
||||||
|
# TODO: Save new template here somewhere?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def after_configuration
|
def after_configuration
|
||||||
app.ignore %r{\.frontmatter$}
|
app.ignore %r{\.frontmatter$}
|
||||||
|
|
||||||
::Middleman::Sitemap::Resource.send :include, ResourceInstanceMethods
|
|
||||||
|
|
||||||
app.sitemap.provides_metadata do |path|
|
|
||||||
fmdata = data(path).first
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
|
|
||||||
[:layout, :layout_engine].each do |opt|
|
|
||||||
data[opt] = fmdata[opt] unless fmdata[opt].nil?
|
|
||||||
end
|
|
||||||
|
|
||||||
if fmdata[:renderer_options]
|
|
||||||
data[:renderer_options] = {}
|
|
||||||
fmdata[:renderer_options].each do |k, v|
|
|
||||||
data[:renderer_options][k.to_sym] = v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
{ options: data }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module ResourceInstanceMethods
|
|
||||||
def ignored?
|
|
||||||
if !proxy? && raw_data[:ignored] == true
|
|
||||||
true
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# This page's frontmatter without being enhanced for access by either symbols or strings.
|
|
||||||
# Used internally
|
|
||||||
# @private
|
|
||||||
# @return [Hash]
|
|
||||||
def raw_data
|
|
||||||
app.extensions[:front_matter].data(source_file).first
|
|
||||||
end
|
|
||||||
|
|
||||||
# This page's frontmatter
|
|
||||||
# @return [Hash]
|
|
||||||
def data
|
|
||||||
@enhanced_data ||= ::Middleman::Util.recursively_enhance(raw_data).freeze
|
|
||||||
end
|
|
||||||
|
|
||||||
# Override Resource#content_type to take into account frontmatter
|
|
||||||
def content_type
|
|
||||||
# Allow setting content type in frontmatter too
|
|
||||||
raw_data.fetch :content_type do
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get the template data from a path
|
# Get the template data from a path
|
||||||
|
|
|
@ -27,9 +27,9 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_configuration
|
def after_configuration
|
||||||
app.files.reload_path(app.config[:locals_dir] || options[:data])
|
app.files.reload_path(app.config[:locales_dir] || options[:data])
|
||||||
|
|
||||||
@locales_glob = File.join(app.config[:locals_dir] || options[:data], '**', '*.{rb,yml,yaml}')
|
@locales_glob = File.join(app.config[:locales_dir] || options[:data], '**', '*.{rb,yml,yaml}')
|
||||||
@locales_regex = convert_glob_to_regex(@locales_glob)
|
@locales_regex = convert_glob_to_regex(@locales_glob)
|
||||||
|
|
||||||
@maps = {}
|
@maps = {}
|
||||||
|
@ -42,7 +42,6 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension
|
||||||
# Don't output localizable files
|
# Don't output localizable files
|
||||||
app.ignore File.join(options[:templates_dir], '**')
|
app.ignore File.join(options[:templates_dir], '**')
|
||||||
|
|
||||||
app.sitemap.provides_metadata_for_path(&method(:metadata_for_path))
|
|
||||||
app.files.changed(&method(:on_file_changed))
|
app.files.changed(&method(:on_file_changed))
|
||||||
app.files.deleted(&method(:on_file_changed))
|
app.files.deleted(&method(:on_file_changed))
|
||||||
end
|
end
|
||||||
|
@ -56,14 +55,12 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension
|
||||||
delegate :logger, to: :app
|
delegate :logger, to: :app
|
||||||
|
|
||||||
def langs
|
def langs
|
||||||
@_langs ||= known_languages
|
@langs ||= known_languages
|
||||||
end
|
end
|
||||||
|
|
||||||
# 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)
|
||||||
@_localization_data = {}
|
|
||||||
|
|
||||||
new_resources = []
|
new_resources = []
|
||||||
|
|
||||||
resources.each do |resource|
|
resources.each do |resource|
|
||||||
|
@ -81,6 +78,12 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension
|
||||||
new_resources << build_resource(path, resource.path, page_id, lang)
|
new_resources << build_resource(path, resource.path, page_id, lang)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This is for backwards compatibility with the old provides_metadata-based code
|
||||||
|
# that used to be in this extension, but I don't know how much sense it makes.
|
||||||
|
unless resource.options[:lang]
|
||||||
|
resource.add_metadata options: { lang: @mount_at_root }, locals: { lang: @mount_at_root }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
resources + new_resources
|
resources + new_resources
|
||||||
|
@ -90,7 +93,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension
|
||||||
|
|
||||||
def on_file_changed(file)
|
def on_file_changed(file)
|
||||||
if @locales_regex =~ file
|
if @locales_regex =~ file
|
||||||
@_langs = nil # Clear langs cache
|
@langs = nil # Clear langs cache
|
||||||
::I18n.reload!
|
::I18n.reload!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -112,24 +115,6 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def metadata_for_path(url)
|
|
||||||
if d = localization_data(url)
|
|
||||||
lang, page_id = d
|
|
||||||
else
|
|
||||||
# Default to the @mount_at_root lang
|
|
||||||
page_id = nil
|
|
||||||
lang = @mount_at_root
|
|
||||||
end
|
|
||||||
|
|
||||||
{
|
|
||||||
locals: {
|
|
||||||
lang: lang,
|
|
||||||
page_id: page_id
|
|
||||||
},
|
|
||||||
options: { lang: lang }
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def known_languages
|
def known_languages
|
||||||
if options[:langs]
|
if options[:langs]
|
||||||
Array(options[:langs]).map(&:to_sym)
|
Array(options[:langs]).map(&:to_sym)
|
||||||
|
@ -144,11 +129,6 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def localization_data(path)
|
|
||||||
@_localization_data ||= {}
|
|
||||||
@_localization_data[path]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Parse locale extension filename
|
# Parse locale extension filename
|
||||||
# @return [lang, path, basename]
|
# @return [lang, path, basename]
|
||||||
# will return +nil+ if no locale extension
|
# will return +nil+ if no locale extension
|
||||||
|
@ -183,10 +163,9 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension
|
||||||
|
|
||||||
path = path.sub(options[:templates_dir] + '/', '')
|
path = path.sub(options[:templates_dir] + '/', '')
|
||||||
|
|
||||||
@_localization_data[path] = [lang, path, localized_page_id]
|
|
||||||
|
|
||||||
p = ::Middleman::Sitemap::Resource.new(app.sitemap, path)
|
p = ::Middleman::Sitemap::Resource.new(app.sitemap, path)
|
||||||
p.proxy_to(source_path)
|
p.proxy_to(source_path)
|
||||||
|
p.add_metadata locals: { lang: lang, page_id: path }, options: { lang: lang }
|
||||||
|
|
||||||
::I18n.locale = old_locale
|
::I18n.locale = old_locale
|
||||||
p
|
p
|
||||||
|
|
|
@ -48,7 +48,7 @@ module Middleman
|
||||||
# Liquid Support
|
# Liquid Support
|
||||||
begin
|
begin
|
||||||
require 'middleman-core/renderers/liquid'
|
require 'middleman-core/renderers/liquid'
|
||||||
app.send :include, Middleman::Renderers::Liquid
|
Middleman::Extensions.register :liquid, Middleman::Renderers::Liquid, auto_activate: :before_configuration
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,43 +1,84 @@
|
||||||
# Routing extension
|
# Routing extension
|
||||||
module Middleman
|
module Middleman
|
||||||
module CoreExtensions
|
module CoreExtensions
|
||||||
module Routing
|
class Routing < Extension
|
||||||
# The page method allows the layout to be set on a specific path
|
# This should always run late, but not as late as :directory_indexes,
|
||||||
|
# so it can add metadata to any pages generated by other extensions
|
||||||
|
self.resource_list_manipulator_priority = 80
|
||||||
|
|
||||||
|
def initialize(app, options_hash={}, &block)
|
||||||
|
super
|
||||||
|
|
||||||
|
@page_configs = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def before_configuration
|
||||||
|
app.add_to_config_context :page, &method(:page)
|
||||||
|
end
|
||||||
|
|
||||||
|
def manipulate_resource_list(resources)
|
||||||
|
resources.each do |resource|
|
||||||
|
@page_configs.each do |matcher, metadata|
|
||||||
|
case matcher
|
||||||
|
when Regexp
|
||||||
|
next unless resource.path =~ matcher
|
||||||
|
when String
|
||||||
|
next unless File.fnmatch('/' + Util.strip_leading_slash(matcher), "/#{resource.path}")
|
||||||
|
end
|
||||||
|
|
||||||
|
resource.add_metadata metadata
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# The page method allows options to be set for a given source path, regex, or glob.
|
||||||
|
# Options that may be set include layout, locals, proxy, andx ignore.
|
||||||
#
|
#
|
||||||
# page "/about.html", layout: false
|
# @example
|
||||||
# page "/", layout: :homepage_layout
|
# page '/about.html', layout: false
|
||||||
|
# @example
|
||||||
|
# page '/index.html', layout: :homepage_layout
|
||||||
|
# @example
|
||||||
|
# page '/foo.html', locals: { foo: 'bar' }
|
||||||
#
|
#
|
||||||
# @param [String] url
|
# @param [String, Regexp] path A source path, or a Regexp/glob that can match multiple resources.
|
||||||
# @param [Hash] opts
|
# @params [Hash] opts Options to apply to all matching resources. Undocumented options are passed on as page metadata to be used by extensions.
|
||||||
|
# @option opts [Symbol, Boolean, String] layout The layout name to use (e.g. `:article`) or `false` to disable layout.
|
||||||
|
# @option opts [Boolean] directory_indexes Whether or not the `:directory_indexes` extension applies to these paths.
|
||||||
|
# @option opts [Hash] locals Local variables for the template. These will be available when the template renders.
|
||||||
|
# @option opts [Hash] data Extra metadata to add to the page. This is the same as frontmatter, though frontmatter will take precedence over metadata defined here. Available via {Resource#data}.
|
||||||
|
# @option opts [String] proxy The source path for a template to proxy this path to. Only valid when a single path is provided. Prefer using the `proxy` method to do this.
|
||||||
|
# @option opts [Boolean] ignore Set to `true` to ignore the provided path(s). Only valid when a single path is provided. Prefer using the `ignore` method to do this.
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def page(url, opts={})
|
def page(path, opts={})
|
||||||
options = opts.dup
|
options = opts.dup
|
||||||
|
|
||||||
# Default layout
|
# Default layout
|
||||||
|
# TODO: This seems wrong
|
||||||
options[:layout] = @app.config[:layout] if options[:layout].nil?
|
options[:layout] = @app.config[:layout] if options[:layout].nil?
|
||||||
metadata = { options: options, locals: options.delete(:locals) || {} }
|
# TODO: You can set options and locals, but not data
|
||||||
|
metadata = { options: options, locals: options.delete(:locals) || {}, page: options.delete(:data) || {} }
|
||||||
|
|
||||||
# If the url is a regexp
|
# If the path is a regexp
|
||||||
unless url.is_a?(Regexp) || url.include?('*')
|
unless path.is_a?(Regexp) || path.include?('*')
|
||||||
# Normalized path
|
# Normalized path
|
||||||
url = '/' + Middleman::Util.normalize_path(url)
|
path = '/' + Middleman::Util.normalize_path(path)
|
||||||
if url.end_with?('/') || File.directory?(File.join(@app.source_dir, url))
|
if path.end_with?('/') || File.directory?(File.join(@app.source_dir, path))
|
||||||
url = File.join(url, @app.config[:index_file])
|
path = File.join(path, @app.config[:index_file])
|
||||||
end
|
end
|
||||||
|
|
||||||
# Setup proxy
|
# Setup proxy
|
||||||
if target = options.delete(:proxy)
|
if target = options.delete(:proxy)
|
||||||
# TODO: deprecate proxy through page?
|
# TODO: deprecate proxy through page?
|
||||||
@app.proxy(url, target, opts.dup)
|
@app.proxy(path, target, opts.dup)
|
||||||
return
|
return
|
||||||
elsif options.delete(:ignore)
|
elsif options.delete(:ignore)
|
||||||
# TODO: deprecate ignore through page?
|
# TODO: deprecate ignore through page?
|
||||||
@app.ignore(url)
|
@app.ignore(path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Setup a metadata matcher for rendering those options
|
@page_configs << [path, metadata]
|
||||||
@app.sitemap.provides_metadata_for_path(url) { |_| metadata }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
|
require 'rack/showexceptions'
|
||||||
|
|
||||||
# Support rack/showexceptions during development
|
# Support rack/showexceptions during development
|
||||||
module Middleman::CoreExtensions
|
module Middleman::CoreExtensions
|
||||||
class ShowExceptions < ::Middleman::Extension
|
class ShowExceptions < ::Middleman::Extension
|
||||||
def initialize(app, options_hash={}, &block)
|
def initialize(app, options_hash={}, &block)
|
||||||
super
|
super
|
||||||
|
|
||||||
require 'rack/showexceptions'
|
app.config.define_setting :show_exceptions, true, 'Whether to catch and display exceptions'
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_configuration
|
def after_configuration
|
||||||
app.use ::Rack::ShowExceptions
|
app.use ::Rack::ShowExceptions if app.config[:show_exceptions]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,11 +16,8 @@ class Middleman::Extensions::DirectoryIndexes < ::Middleman::Extension
|
||||||
resource.destination_path.end_with?(new_index_path) ||
|
resource.destination_path.end_with?(new_index_path) ||
|
||||||
File.extname(index_file) != resource.ext
|
File.extname(index_file) != resource.ext
|
||||||
|
|
||||||
# Check if frontmatter turns directory_index off
|
# Check if file metadata (options set by "page" in config.rb or frontmatter) turns directory_index off
|
||||||
next if resource.raw_data[:directory_index] == false
|
next if resource.options[:directory_index] == false
|
||||||
|
|
||||||
# Check if file metadata (options set by "page" in config.rb) turns directory_index off
|
|
||||||
next if resource.metadata[:options][:directory_index] == false
|
|
||||||
|
|
||||||
resource.destination_path = resource.destination_path.chomp(File.extname(index_file)) + new_index_path
|
resource.destination_path = resource.destination_path.chomp(File.extname(index_file)) + new_index_path
|
||||||
end
|
end
|
||||||
|
|
|
@ -44,11 +44,10 @@ module Middleman
|
||||||
data = @resource.data
|
data = @resource.data
|
||||||
props['Data'] = data.inspect unless data.empty?
|
props['Data'] = data.inspect unless data.empty?
|
||||||
|
|
||||||
meta = @resource.metadata
|
options = @resource.options
|
||||||
options = meta[:options]
|
|
||||||
props['Options'] = options.inspect unless options.empty?
|
props['Options'] = options.inspect unless options.empty?
|
||||||
|
|
||||||
locals = meta[:locals].keys
|
locals = @resource.locals.keys
|
||||||
props['Locals'] = locals.join(', ') unless locals.empty?
|
props['Locals'] = locals.join(', ') unless locals.empty?
|
||||||
|
|
||||||
props
|
props
|
||||||
|
|
|
@ -4,23 +4,19 @@ require 'liquid'
|
||||||
module Middleman
|
module Middleman
|
||||||
module Renderers
|
module Renderers
|
||||||
# Liquid Renderer
|
# Liquid Renderer
|
||||||
module Liquid
|
class Liquid < Middleman::Extension
|
||||||
# Setup extension
|
|
||||||
class << self
|
|
||||||
# Once registerd
|
|
||||||
def registered(app)
|
|
||||||
# After config, setup liquid partial paths
|
# After config, setup liquid partial paths
|
||||||
app.after_configuration do
|
def after_configuration
|
||||||
::Liquid::Template.file_system = ::Liquid::LocalFileSystem.new(source_dir)
|
::Liquid::Template.file_system = ::Liquid::LocalFileSystem.new(app.source_dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
def manipulate_resource_list(resources)
|
||||||
|
resources.each do |resource|
|
||||||
# Convert data object into a hash for liquid
|
# Convert data object into a hash for liquid
|
||||||
sitemap.provides_metadata %r{\.liquid$} do
|
if resource.source_file =~ %r{\.liquid$}
|
||||||
{ locals: { data: data.to_h } }
|
resource.add_metadata locals: { data: app.data.to_h }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
alias_method :included, :registered
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,8 +5,8 @@ module Middleman::Sitemap::Extensions
|
||||||
module ContentType
|
module ContentType
|
||||||
# The preferred MIME content type for this resource
|
# The preferred MIME content type for this resource
|
||||||
def content_type
|
def content_type
|
||||||
# Allow explcitly setting content type from page/proxy options
|
# Allow explcitly setting content type from page/proxy options or frontmatter
|
||||||
meta_type = metadata[:options][:content_type]
|
meta_type = options[:content_type]
|
||||||
return meta_type if meta_type
|
return meta_type if meta_type
|
||||||
|
|
||||||
# Look up mime type based on extension
|
# Look up mime type based on extension
|
||||||
|
|
|
@ -3,15 +3,15 @@ module Middleman
|
||||||
module Extensions
|
module Extensions
|
||||||
# Class to handle managing ignores
|
# Class to handle managing ignores
|
||||||
class Ignores
|
class Ignores
|
||||||
def initialize(sitemap)
|
def initialize(app, sitemap)
|
||||||
@app = sitemap.app
|
@app = app
|
||||||
@app.add_to_config_context :ignore, &method(:create_ignore)
|
@app.add_to_config_context :ignore, &method(:create_ignore)
|
||||||
@app.define_singleton_method(:ignore, &method(:create_ignore))
|
@app.define_singleton_method :ignore, &method(:create_ignore)
|
||||||
|
|
||||||
# Array of callbacks which can ass ignored
|
# Array of callbacks which can ass ignored
|
||||||
@ignored_callbacks = []
|
@ignored_callbacks = []
|
||||||
|
|
||||||
sitemap.define_singleton_method(:ignored?, &method(:ignored?))
|
sitemap.define_singleton_method :ignored?, &method(:ignored?)
|
||||||
::Middleman::Sitemap::Resource.send :include, IgnoreResourceInstanceMethods
|
::Middleman::Sitemap::Resource.send :include, IgnoreResourceInstanceMethods
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -48,13 +48,20 @@ module Middleman
|
||||||
|
|
||||||
# Helpers methods for Resources
|
# Helpers methods for Resources
|
||||||
module IgnoreResourceInstanceMethods
|
module IgnoreResourceInstanceMethods
|
||||||
|
# Ignore a resource directly, without going through the whole
|
||||||
|
# ignore filter stuff.
|
||||||
|
def ignore!
|
||||||
|
@ignored = true
|
||||||
|
end
|
||||||
|
|
||||||
# Whether the Resource is ignored
|
# Whether the Resource is ignored
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
def ignored?
|
def ignored?
|
||||||
@app.sitemap.ignored?(path) ||
|
return true if @ignored
|
||||||
(!proxy? &&
|
# Ignore based on the source path (without template extensions)
|
||||||
@app.sitemap.ignored?(source_file.sub("#{@app.source_dir}/", ''))
|
return true if @app.sitemap.ignored?(path)
|
||||||
)
|
# This allows files to be ignored by their source file name (with template extensions)
|
||||||
|
!proxy? && @app.sitemap.ignored?(source_file.sub("#{@app.source_dir}/", ''))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,23 +7,25 @@ module Middleman
|
||||||
attr_accessor :sitemap
|
attr_accessor :sitemap
|
||||||
attr_accessor :waiting_for_ready
|
attr_accessor :waiting_for_ready
|
||||||
|
|
||||||
def initialize(sitemap)
|
def initialize(app, sitemap)
|
||||||
@sitemap = sitemap
|
@sitemap = sitemap
|
||||||
@app = @sitemap.app
|
@app = app
|
||||||
@file_paths_on_disk = Set.new
|
@file_paths_on_disk = Set.new
|
||||||
|
|
||||||
scoped_self = self
|
scoped_self = self
|
||||||
@waiting_for_ready = true
|
@waiting_for_ready = true
|
||||||
|
|
||||||
|
@app.before_configuration do
|
||||||
# Register file change callback
|
# Register file change callback
|
||||||
@app.files.changed do |file|
|
files.changed do |file|
|
||||||
scoped_self.touch_file(file)
|
scoped_self.touch_file(file)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Register file delete callback
|
# Register file delete callback
|
||||||
@app.files.deleted do |file|
|
files.deleted do |file|
|
||||||
scoped_self.remove_file(file)
|
scoped_self.remove_file(file)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@app.ready do
|
@app.ready do
|
||||||
scoped_self.waiting_for_ready = false
|
scoped_self.waiting_for_ready = false
|
||||||
|
|
|
@ -4,8 +4,8 @@ module Middleman
|
||||||
# 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 Proxies
|
class Proxies
|
||||||
def initialize(sitemap)
|
def initialize(app)
|
||||||
@app = sitemap.app
|
@app = app
|
||||||
@app.add_to_config_context :proxy, &method(:create_proxy)
|
@app.add_to_config_context :proxy, &method(:create_proxy)
|
||||||
@app.define_singleton_method(:proxy, &method(:create_proxy))
|
@app.define_singleton_method(:proxy, &method(:create_proxy))
|
||||||
|
|
||||||
|
@ -109,10 +109,10 @@ module Middleman
|
||||||
# if there is no resource.
|
# if there is no resource.
|
||||||
# @return [Sitemap::Resource]
|
# @return [Sitemap::Resource]
|
||||||
def proxied_to_resource
|
def proxied_to_resource
|
||||||
proxy_resource = store.find_resource_by_path(proxied_to)
|
proxy_resource = @store.find_resource_by_path(proxied_to)
|
||||||
|
|
||||||
unless proxy_resource
|
unless proxy_resource
|
||||||
raise "Path #{path} proxies to unknown file #{proxied_to}:#{store.resources.map(&:path)}"
|
raise "Path #{path} proxies to unknown file #{proxied_to}:#{@store.resources.map(&:path)}"
|
||||||
end
|
end
|
||||||
|
|
||||||
if proxy_resource.proxy?
|
if proxy_resource.proxy?
|
||||||
|
|
|
@ -6,8 +6,8 @@ module Middleman
|
||||||
# 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 Redirects
|
class Redirects
|
||||||
def initialize(sitemap)
|
def initialize(app)
|
||||||
@app = sitemap.app
|
@app = app
|
||||||
@app.add_to_config_context :redirect, &method(:create_redirect)
|
@app.add_to_config_context :redirect, &method(:create_redirect)
|
||||||
|
|
||||||
@redirects = {}
|
@redirects = {}
|
||||||
|
@ -53,7 +53,7 @@ module Middleman
|
||||||
end
|
end
|
||||||
|
|
||||||
def render(*)
|
def render(*)
|
||||||
url = ::Middleman::Util.url_for(store.app, @request_path,
|
url = ::Middleman::Util.url_for(@store.app, @request_path,
|
||||||
relative: false,
|
relative: false,
|
||||||
find_resource: true
|
find_resource: true
|
||||||
)
|
)
|
||||||
|
@ -75,24 +75,17 @@ module Middleman
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# def request_path
|
|
||||||
# @request_path
|
|
||||||
# end
|
|
||||||
|
|
||||||
def binary?
|
def binary?
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def raw_data
|
|
||||||
{}
|
|
||||||
end
|
|
||||||
|
|
||||||
def ignored?
|
def ignored?
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def metadata
|
# rubocop:disable AccessorMethodName
|
||||||
@local_metadata.dup
|
def get_source_file
|
||||||
|
''
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,8 +4,8 @@ module Middleman
|
||||||
class RequestEndpoints
|
class RequestEndpoints
|
||||||
# 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
|
||||||
def initialize(sitemap)
|
def initialize(app)
|
||||||
@app = sitemap.app
|
@app = app
|
||||||
@app.add_to_config_context :endpoint, &method(:create_endpoint)
|
@app.add_to_config_context :endpoint, &method(:create_endpoint)
|
||||||
|
|
||||||
@endpoints = {}
|
@endpoints = {}
|
||||||
|
@ -49,12 +49,13 @@ module Middleman
|
||||||
class EndpointResource < ::Middleman::Sitemap::Resource
|
class EndpointResource < ::Middleman::Sitemap::Resource
|
||||||
attr_accessor :output
|
attr_accessor :output
|
||||||
|
|
||||||
def initialize(store, path, source_file)
|
def initialize(store, path, request_path)
|
||||||
@request_path = ::Middleman::Util.normalize_path(source_file)
|
|
||||||
|
|
||||||
super(store, path)
|
super(store, path)
|
||||||
|
@request_path = ::Middleman::Util.normalize_path(request_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
attr_reader :request_path
|
||||||
|
|
||||||
def template?
|
def template?
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
@ -63,22 +64,17 @@ module Middleman
|
||||||
return output.call if output
|
return output.call if output
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :request_path
|
|
||||||
|
|
||||||
def binary?
|
def binary?
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def raw_data
|
|
||||||
{}
|
|
||||||
end
|
|
||||||
|
|
||||||
def ignored?
|
def ignored?
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def metadata
|
# rubocop:disable AccessorMethodName
|
||||||
@local_metadata.dup
|
def get_source_file
|
||||||
|
''
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,13 +7,13 @@ module Middleman
|
||||||
def parent
|
def parent
|
||||||
parts = path.split('/')
|
parts = path.split('/')
|
||||||
tail = parts.pop
|
tail = parts.pop
|
||||||
is_index = (tail == app.config[:index_file])
|
is_index = (tail == @app.config[:index_file])
|
||||||
|
|
||||||
return nil if is_index && parts.length < 1
|
return nil if is_index && parts.length < 1
|
||||||
|
|
||||||
test_expr = parts.join('\\/')
|
test_expr = parts.join('\\/')
|
||||||
# eponymous reverse-lookup
|
# eponymous reverse-lookup
|
||||||
found = store.resources.find do |candidate|
|
found = @store.resources.find do |candidate|
|
||||||
candidate.path =~ %r!^#{test_expr}(?:\.[a-zA-Z0-9]+|\/)$!
|
candidate.path =~ %r!^#{test_expr}(?:\.[a-zA-Z0-9]+|\/)$!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ module Middleman
|
||||||
found
|
found
|
||||||
else
|
else
|
||||||
parts.pop if is_index
|
parts.pop if is_index
|
||||||
store.find_resource_by_destination_path("#{parts.join('/')}/#{app.config[:index_file]}")
|
@store.find_resource_by_destination_path("#{parts.join('/')}/#{@app.config[:index_file]}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -34,11 +34,11 @@ 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.config[:index_file]}", '')
|
base_path = path.sub("#{@app.config[:index_file]}", '')
|
||||||
prefix = %r{^#{base_path.sub("/", "\\/")}}
|
prefix = %r{^#{base_path.sub("/", "\\/")}}
|
||||||
end
|
end
|
||||||
|
|
||||||
store.resources.select do |sub_resource|
|
@store.resources.select do |sub_resource|
|
||||||
if sub_resource.path == path || sub_resource.path !~ prefix
|
if sub_resource.path == path || sub_resource.path !~ prefix
|
||||||
false
|
false
|
||||||
else
|
else
|
||||||
|
@ -47,7 +47,7 @@ module Middleman
|
||||||
if parts.length == 1
|
if parts.length == 1
|
||||||
true
|
true
|
||||||
elsif parts.length == 2
|
elsif parts.length == 2
|
||||||
parts.last == app.config[:index_file]
|
parts.last == @app.config[:index_file]
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
@ -65,17 +65,17 @@ module Middleman
|
||||||
# Whether this resource is either a directory index, or has the same name as an existing directory in the source
|
# Whether this resource is 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.config[: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.config[:index_file]}") && destination_path.end_with?("/#{app.config[: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)
|
||||||
File.exist?(full_path) && File.directory?(full_path)
|
File.exist?(full_path) && File.directory?(full_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -11,27 +11,24 @@ module Middleman
|
||||||
include Middleman::Sitemap::Extensions::Traversal
|
include Middleman::Sitemap::Extensions::Traversal
|
||||||
include Middleman::Sitemap::Extensions::ContentType
|
include Middleman::Sitemap::Extensions::ContentType
|
||||||
|
|
||||||
# @return [Middleman::Application]
|
|
||||||
attr_reader :app
|
|
||||||
delegate :logger, :instrument, to: :app
|
|
||||||
|
|
||||||
# @return [Middleman::Sitemap::Store]
|
|
||||||
attr_reader :store
|
|
||||||
|
|
||||||
# The source path of this resource (relative to the source directory,
|
# The source path of this resource (relative to the source directory,
|
||||||
# without template extensions)
|
# without template extensions)
|
||||||
# @return [String]
|
# @return [String]
|
||||||
attr_reader :path
|
attr_reader :path
|
||||||
|
|
||||||
# The output path for this resource
|
# The output path in the build directory for this resource
|
||||||
# @return [String]
|
# @return [String]
|
||||||
attr_accessor :destination_path
|
attr_accessor :destination_path
|
||||||
|
|
||||||
|
# The path to use when requesting this resource. Normally it's
|
||||||
|
# the same as {#destination_path} but it can be overridden in subclasses.
|
||||||
|
# @return [String]
|
||||||
|
alias_method :request_path, :destination_path
|
||||||
|
|
||||||
# Set the on-disk source file for this resource
|
# Set the on-disk source file for this resource
|
||||||
# @return [String]
|
# @return [String]
|
||||||
# attr_reader :source_file
|
|
||||||
|
|
||||||
def source_file
|
def source_file
|
||||||
|
# TODO: Make this work when get_source_file doesn't exist
|
||||||
@source_file || get_source_file
|
@source_file || get_source_file
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -46,7 +43,11 @@ module Middleman
|
||||||
@source_file = source_file
|
@source_file = source_file
|
||||||
@destination_path = @path
|
@destination_path = @path
|
||||||
|
|
||||||
@local_metadata = { options: {}, locals: {} }
|
# Options are generally rendering/sitemap options
|
||||||
|
# Locals are local variables for rendering this resource's template
|
||||||
|
# Page are data that is exposed through this resource's data member.
|
||||||
|
# Note: It is named 'page' for backwards compatibility with older MM.
|
||||||
|
@metadata = { options: {}, locals: {}, page: {} }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Whether this resource has a template file
|
# Whether this resource has a template file
|
||||||
|
@ -56,29 +57,39 @@ module Middleman
|
||||||
!::Tilt[source_file].nil?
|
!::Tilt[source_file].nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get the metadata for both the current source_file and the current path
|
|
||||||
# @return [Hash]
|
|
||||||
def metadata
|
|
||||||
result = store.metadata_for_path(path).dup
|
|
||||||
|
|
||||||
file_meta = store.metadata_for_file(source_file).dup
|
|
||||||
result.deep_merge!(file_meta)
|
|
||||||
|
|
||||||
local_meta = @local_metadata.dup
|
|
||||||
result.deep_merge!(local_meta)
|
|
||||||
|
|
||||||
result
|
|
||||||
end
|
|
||||||
|
|
||||||
# Merge in new metadata specific to this resource.
|
# Merge in new metadata specific to this resource.
|
||||||
# @param [Hash] meta A metadata block like provides_metadata_for_path takes
|
# @param [Hash] meta A metadata block with keys :options, :locals, :page.
|
||||||
|
# Options are generally rendering/sitemap options
|
||||||
|
# Locals are local variables for rendering this resource's template
|
||||||
|
# Page are data that is exposed through this resource's data member.
|
||||||
|
# Note: It is named 'page' for backwards compatibility with older MM.
|
||||||
def add_metadata(meta={})
|
def add_metadata(meta={})
|
||||||
@local_metadata.deep_merge!(meta.dup)
|
@metadata.deep_merge!(meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
# The output/preview URL for this resource
|
# The metadata for this resource
|
||||||
# @return [String]
|
# @return [Hash]
|
||||||
attr_accessor :destination_path
|
attr_reader :metadata
|
||||||
|
|
||||||
|
# Data about this resource, populated from frontmatter or extensions.
|
||||||
|
# @return [HashWithIndifferentAccess]
|
||||||
|
def data
|
||||||
|
# TODO: Should this really be a HashWithIndifferentAccess?
|
||||||
|
::Middleman::Util.recursively_enhance(metadata[:page]).freeze
|
||||||
|
end
|
||||||
|
|
||||||
|
# Options about how this resource is rendered, such as its :layout,
|
||||||
|
# :renderer_options, and whether or not to use :directory_indexes.
|
||||||
|
# @return [Hash]
|
||||||
|
def options
|
||||||
|
metadata[:options]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Local variable mappings that are used when rendering the template for this resource.
|
||||||
|
# @return [Hash]
|
||||||
|
def locals
|
||||||
|
metadata[:locals]
|
||||||
|
end
|
||||||
|
|
||||||
# Extension of the path (i.e. '.js')
|
# Extension of the path (i.e. '.js')
|
||||||
# @return [String]
|
# @return [String]
|
||||||
|
@ -86,19 +97,15 @@ module Middleman
|
||||||
File.extname(path)
|
File.extname(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def request_path
|
|
||||||
destination_path
|
|
||||||
end
|
|
||||||
|
|
||||||
# Render this resource
|
# Render this resource
|
||||||
# @return [String]
|
# @return [String]
|
||||||
def render(opts={}, locs={})
|
def render(opts={}, locs={})
|
||||||
return ::Middleman::FileRenderer.new(@app, source_file).template_data_for_file unless template?
|
return ::Middleman::FileRenderer.new(@app, source_file).template_data_for_file unless template?
|
||||||
|
|
||||||
relative_source = Pathname(source_file).relative_path_from(Pathname(app.root))
|
relative_source = Pathname(source_file).relative_path_from(Pathname(@app.root))
|
||||||
|
|
||||||
instrument 'render.resource', path: relative_source, destination_path: destination_path do
|
@app.instrument 'render.resource', path: relative_source, destination_path: destination_path do
|
||||||
md = metadata.dup
|
md = metadata
|
||||||
opts = md[:options].deep_merge(opts)
|
opts = md[:options].deep_merge(opts)
|
||||||
locs = md[:locals].deep_merge(locs)
|
locs = md[:locals].deep_merge(locs)
|
||||||
locs[:current_path] ||= destination_path
|
locs[:current_path] ||= destination_path
|
||||||
|
@ -118,11 +125,11 @@ module Middleman
|
||||||
# @return [String]
|
# @return [String]
|
||||||
def url
|
def url
|
||||||
url_path = destination_path
|
url_path = destination_path
|
||||||
if app.config[:strip_index_file]
|
if @app.config[:strip_index_file]
|
||||||
url_path = url_path.sub(/(^|\/)#{Regexp.escape(app.config[:index_file])}$/,
|
url_path = url_path.sub(/(^|\/)#{Regexp.escape(@app.config[:index_file])}$/,
|
||||||
app.config[:trailing_slash] ? '/' : '')
|
@app.config[:trailing_slash] ? '/' : '')
|
||||||
end
|
end
|
||||||
File.join(app.config[: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.
|
||||||
|
|
|
@ -20,14 +20,14 @@ module Middleman
|
||||||
# extensions. All "path" parameters used in this class are source paths.
|
# extensions. All "path" parameters used in this class are source paths.
|
||||||
class Store
|
class Store
|
||||||
# @return [Middleman::Application]
|
# @return [Middleman::Application]
|
||||||
attr_accessor :app
|
attr_reader :app
|
||||||
|
|
||||||
# Initialize with parent app
|
# Initialize with parent app
|
||||||
# @param [Middleman::Application] app
|
# @param [Middleman::Application] app
|
||||||
def initialize(app)
|
def initialize(app)
|
||||||
@app = app
|
@app = app
|
||||||
@resources = []
|
@resources = []
|
||||||
@_cached_metadata = {}
|
# TODO: Should this be a set or hash?
|
||||||
@resource_list_manipulators = []
|
@resource_list_manipulators = []
|
||||||
@needs_sitemap_rebuild = true
|
@needs_sitemap_rebuild = true
|
||||||
|
|
||||||
|
@ -35,26 +35,26 @@ module Middleman
|
||||||
reset_lookup_cache!
|
reset_lookup_cache!
|
||||||
|
|
||||||
# Handle ignore commands
|
# Handle ignore commands
|
||||||
Middleman::Sitemap::Extensions::Ignores.new(self)
|
Middleman::Sitemap::Extensions::Ignores.new(@app, self)
|
||||||
|
|
||||||
# Extensions
|
# Extensions
|
||||||
{
|
{
|
||||||
# Register classes which can manipulate the main site map list
|
# Register classes which can manipulate the main site map list
|
||||||
on_disk: Middleman::Sitemap::Extensions::OnDisk,
|
on_disk: Middleman::Sitemap::Extensions::OnDisk.new(@app, self),
|
||||||
|
|
||||||
# Request Endpoints
|
# Request Endpoints
|
||||||
request_endpoints: Middleman::Sitemap::Extensions::RequestEndpoints,
|
request_endpoints: Middleman::Sitemap::Extensions::RequestEndpoints.new(@app),
|
||||||
|
|
||||||
# Proxies
|
# Proxies
|
||||||
proxies: Middleman::Sitemap::Extensions::Proxies,
|
proxies: Middleman::Sitemap::Extensions::Proxies.new(@app),
|
||||||
|
|
||||||
# Redirects
|
# Redirects
|
||||||
redirects: Middleman::Sitemap::Extensions::Redirects
|
redirects: Middleman::Sitemap::Extensions::Redirects.new(@app)
|
||||||
}.each do |k, m|
|
}.each do |k, m|
|
||||||
register_resource_list_manipulator(k, m.new(self))
|
register_resource_list_manipulator(k, m)
|
||||||
end
|
end
|
||||||
|
|
||||||
app.config_context.class.send :delegate, :sitemap, to: :app
|
@app.config_context.class.send :delegate, :sitemap, to: :app
|
||||||
end
|
end
|
||||||
|
|
||||||
# Register an object which can transform the sitemap resource list. Best to register
|
# Register an object which can transform the sitemap resource list. Best to register
|
||||||
|
@ -128,63 +128,6 @@ module Middleman
|
||||||
@resources_not_ignored = nil
|
@resources_not_ignored = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# Register a handler to provide metadata on a file path
|
|
||||||
# @param [Regexp] matcher
|
|
||||||
# @return [Array<Array<Proc, Regexp>>]
|
|
||||||
def provides_metadata(matcher=nil, &block)
|
|
||||||
@_provides_metadata ||= []
|
|
||||||
@_provides_metadata << [block, matcher] if block_given?
|
|
||||||
@_provides_metadata
|
|
||||||
end
|
|
||||||
|
|
||||||
# Get the metadata for a specific file
|
|
||||||
# @param [String] source_file
|
|
||||||
# @return [Hash]
|
|
||||||
def metadata_for_file(source_file)
|
|
||||||
blank_metadata = { options: {}, locals: {} }
|
|
||||||
|
|
||||||
provides_metadata.reduce(blank_metadata) do |result, (callback, matcher)|
|
|
||||||
next result if matcher && !source_file.match(matcher)
|
|
||||||
|
|
||||||
metadata = callback.call(source_file).dup
|
|
||||||
result.deep_merge(metadata)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Register a handler to provide metadata on a url path
|
|
||||||
# @param [Regexp] matcher
|
|
||||||
# @return [Array<Array<Proc, Regexp>>]
|
|
||||||
def provides_metadata_for_path(matcher=nil, &block)
|
|
||||||
@_provides_metadata_for_path ||= []
|
|
||||||
if block_given?
|
|
||||||
@_provides_metadata_for_path << [block, matcher]
|
|
||||||
@_cached_metadata = {}
|
|
||||||
end
|
|
||||||
@_provides_metadata_for_path
|
|
||||||
end
|
|
||||||
|
|
||||||
# Get the metadata for a specific URL
|
|
||||||
# @param [String] request_path
|
|
||||||
# @return [Hash]
|
|
||||||
def metadata_for_path(request_path)
|
|
||||||
return @_cached_metadata[request_path] if @_cached_metadata[request_path]
|
|
||||||
|
|
||||||
blank_metadata = { options: {}, locals: {} }
|
|
||||||
|
|
||||||
@_cached_metadata[request_path] = provides_metadata_for_path.reduce(blank_metadata) do |result, (callback, matcher)|
|
|
||||||
case matcher
|
|
||||||
when Regexp
|
|
||||||
next result unless request_path =~ matcher
|
|
||||||
when String
|
|
||||||
next result unless File.fnmatch('/' + Util.strip_leading_slash(matcher), "/#{request_path}")
|
|
||||||
end
|
|
||||||
|
|
||||||
metadata = callback.call(request_path).dup
|
|
||||||
|
|
||||||
result.deep_merge(metadata)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Get the URL path for an on-disk file
|
# Get the URL path for an on-disk file
|
||||||
# @param [String] file
|
# @param [String] file
|
||||||
# @return [String]
|
# @return [String]
|
||||||
|
|
|
@ -41,12 +41,11 @@ Given /^the Server is running$/ do
|
||||||
ENV['MM_ROOT'] = root_dir
|
ENV['MM_ROOT'] = root_dir
|
||||||
|
|
||||||
initialize_commands = @initialize_commands || []
|
initialize_commands = @initialize_commands || []
|
||||||
|
initialize_commands.unshift lambda { config[:show_exceptions] = false }
|
||||||
|
|
||||||
@server_inst = Middleman::Application.server.inst do
|
@server_inst = Middleman::Application.server.inst do
|
||||||
app.initialized do
|
|
||||||
initialize_commands.each do |p|
|
initialize_commands.each do |p|
|
||||||
config_context.instance_exec(&p)
|
instance_exec(&p)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue