Merge pull request #1313 from bhollis/remove_neighbor

Remove neighbor frontmatter support & move resource methods into Resource
This commit is contained in:
Ben Hollis 2014-07-07 22:49:23 -07:00
commit 50c6b3f4b9
10 changed files with 119 additions and 128 deletions

View file

@ -0,0 +1,27 @@
ignore '*.frontmatter'
# Reads neighbor for every file on every refresh.
# TODO: Optimize
class NeighborFrontmatter < ::Middleman::Extension
self.resource_list_manipulator_priority = 81
def manipulate_resource_list(resources)
resources.each do |resource|
next unless resource.source_file
neighbor = "#{resource.source_file}.frontmatter"
if File.exists?(neighbor)
fmdata = app.extensions[:front_matter].frontmatter_and_content(neighbor).first
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)
resource.add_metadata options: opts, page: fmdata
resource.ignore! if ignored == true && !resource.is_a?(::Middleman::Sitemap::ProxyResource)
end
end
end
end
Middleman::Extensions.register :neighbor_frontmatter, NeighborFrontmatter unless Middleman::Extensions.registered.include? :neighbor_frontmatter
activate :neighbor_frontmatter

View file

@ -2,3 +2,31 @@
proxy 'proxied.html', 'ignored.html' proxy 'proxied.html', 'ignored.html'
page 'override_layout.html', layout: :alternate page 'override_layout.html', layout: :alternate
page 'page_mentioned.html' page 'page_mentioned.html'
ignore '*.frontmatter'
# Reads neighbor for every file on every refresh.
# TODO: Optimize
class NeighborFrontmatter < ::Middleman::Extension
self.resource_list_manipulator_priority = 81
def manipulate_resource_list(resources)
resources.each do |resource|
next unless resource.source_file
neighbor = "#{resource.source_file}.frontmatter"
if File.exists?(neighbor)
fmdata = app.extensions[:front_matter].frontmatter_and_content(neighbor).first
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)
resource.add_metadata options: opts, page: fmdata
resource.ignore! if ignored == true && !resource.is_a?(::Middleman::Sitemap::ProxyResource)
end
end
end
end
Middleman::Extensions.register :neighbor_frontmatter, NeighborFrontmatter unless Middleman::Extensions.registered.include? :neighbor_frontmatter
activate :neighbor_frontmatter

View file

@ -57,10 +57,6 @@ module Middleman::CoreExtensions
end end
end end
def after_configuration
app.ignore %r{\.frontmatter$}
end
# Get the template data from a path # Get the template data from a path
# @param [String] path # @param [String] path
# @return [String] # @return [String]
@ -70,16 +66,7 @@ module Middleman::CoreExtensions
def data(path) def data(path)
p = normalize_path(path) p = normalize_path(path)
@cache[p] ||= begin @cache[p] ||= frontmatter_and_content(p)
data, content = frontmatter_and_content(p)
if file_watcher.exists?("#{path}.frontmatter")
external_data, _ = frontmatter_and_content("#{p}.frontmatter")
data = external_data.deep_merge(data)
end
[data, content]
end
end end
def clear_data(file) def clear_data(file)
@ -88,11 +75,43 @@ module Middleman::CoreExtensions
file = File.join(app.root, file) file = File.join(app.root, file)
prefix = app.source_dir.sub(/\/$/, '') + '/' prefix = app.source_dir.sub(/\/$/, '') + '/'
return unless file.include?(prefix) return unless file.include?(prefix)
path = file.sub(prefix, '').sub(/\.frontmatter$/, '') path = file.sub(prefix, '')
@cache.delete(path) @cache.delete(path)
end end
# Get the frontmatter and plain content from a file
# @param [String] path
# @return [Array<Middleman::Util::HashWithIndifferentAccess, String>]
def frontmatter_and_content(path)
full_path = if Pathname(path).relative?
File.join(app.source_dir, path)
else
path
end
data = {}
return [data, nil] if !file_watcher.exists?(full_path) || ::Middleman::Util.binary?(full_path)
content = File.read(full_path)
begin
if content =~ /\A.*coding:/
lines = content.split(/\n/)
lines.shift
content = lines.join("\n")
end
result = parse_yaml_front_matter(content, full_path) || parse_json_front_matter(content, full_path)
return result if result
rescue
# Probably a binary file, move on
end
[data, content]
end
private private
# Parse YAML frontmatter out of a string # Parse YAML frontmatter out of a string
@ -142,38 +161,6 @@ module Middleman::CoreExtensions
[{}, content] [{}, content]
end end
# Get the frontmatter and plain content from a file
# @param [String] path
# @return [Array<Middleman::Util::HashWithIndifferentAccess, String>]
def frontmatter_and_content(path)
full_path = if Pathname(path).relative?
File.join(app.source_dir, path)
else
path
end
data = {}
return [data, nil] if !file_watcher.exists?(full_path) || ::Middleman::Util.binary?(full_path)
content = File.read(full_path)
begin
if content =~ /\A.*coding:/
lines = content.split(/\n/)
lines.shift
content = lines.join("\n")
end
result = parse_yaml_front_matter(content, full_path) || parse_json_front_matter(content, full_path)
return result if result
rescue
# Probably a binary file, move on
end
[data, content]
end
def normalize_path(path) def normalize_path(path)
path.sub(%r{^#{Regexp.escape(app.source_dir)}\/}, '') path.sub(%r{^#{Regexp.escape(app.source_dir)}\/}, '')
end end

View file

@ -45,8 +45,6 @@ module Middleman
options = opts.dup options = opts.dup
# Default layout # Default layout
# TODO: This seems wrong
options[:layout] = @app.config[:layout] if options[:layout].nil?
metadata = { metadata = {
options: options, options: options,
locals: options.delete(:locals) || {}, locals: options.delete(:locals) || {},

View file

@ -1,16 +0,0 @@
require 'rack'
module Middleman::Sitemap::Extensions
# Content type is implemented as a module so it can be overridden by other sitemap extensions
module ContentType
# The preferred MIME content type for this resource
def content_type
# Allow explcitly setting content type from page/proxy options or frontmatter
meta_type = options[:content_type]
return meta_type if meta_type
# Look up mime type based on extension
::Rack::Mime.mime_type(ext, nil)
end
end
end

View file

@ -12,7 +12,6 @@ module Middleman
@ignored_callbacks = [] @ignored_callbacks = []
sitemap.define_singleton_method :ignored?, &method(:ignored?) sitemap.define_singleton_method :ignored?, &method(:ignored?)
::Middleman::Sitemap::Resource.send :include, IgnoreResourceInstanceMethods
end end
# Ignore a path or add an ignore callback # Ignore a path or add an ignore callback
@ -45,27 +44,6 @@ module Middleman
@ignored_callbacks.any? { |b| b.call(path_clean) } @ignored_callbacks.any? { |b| b.call(path_clean) }
end end
end end
# Helpers methods for Resources
module IgnoreResourceInstanceMethods
# Ignore a resource directly, without going through the whole
# ignore filter stuff.
def ignore!
@ignored = true
end
# Whether the Resource is ignored
# @return [Boolean]
def ignored?
return true if @ignored
# Ignore based on the source path (without template extensions)
return true if @app.sitemap.ignored?(path)
# This allows files to be ignored by their source file name (with template extensions)
@app.sitemap.ignored?(source_file.sub("#{@app.source_dir}/", ''))
end
end
end end
end end
end end

View file

@ -119,8 +119,7 @@ module Middleman
resource resource
end end
# rubocop:disable AccessorMethodName def source_file
def get_source_file
target_resource.source_file target_resource.source_file
end end
@ -130,17 +129,6 @@ module Middleman
target_resource.content_type target_resource.content_type
end end
# Whether the Resource is ignored
# @return [Boolean]
def ignored?
return true if @ignored
# Ignore based on the source path (without template extensions)
return true if @app.sitemap.ignored?(path)
false
end
end end
end end
end end

View file

@ -75,18 +75,9 @@ module Middleman
end end
end end
def binary?
false
end
def ignored? def ignored?
false false
end end
# rubocop:disable AccessorMethodName
def get_source_file
''
end
end end
end end
end end

View file

@ -64,18 +64,9 @@ module Middleman
return output.call if output return output.call if output
end end
def binary?
false
end
def ignored? def ignored?
false false
end end
# rubocop:disable AccessorMethodName
def get_source_file
''
end
end end
end end
end end

View file

@ -1,5 +1,5 @@
require 'rack/mime'
require 'middleman-core/sitemap/extensions/traversal' require 'middleman-core/sitemap/extensions/traversal'
require 'middleman-core/sitemap/extensions/content_type'
require 'middleman-core/file_renderer' require 'middleman-core/file_renderer'
require 'middleman-core/template_renderer' require 'middleman-core/template_renderer'
@ -9,7 +9,6 @@ module Middleman
# Sitemap Resource class # Sitemap Resource class
class Resource class Resource
include Middleman::Sitemap::Extensions::Traversal include Middleman::Sitemap::Extensions::Traversal
include Middleman::Sitemap::Extensions::ContentType
# 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)
@ -20,6 +19,10 @@ module Middleman
# @return [String] # @return [String]
attr_accessor :destination_path attr_accessor :destination_path
# The on-disk source file for this resource, if there is one
# @return [String]
attr_reader :source_file
# The path to use when requesting this resource. Normally it's # The path to use when requesting this resource. Normally it's
# the same as {#destination_path} but it can be overridden in subclasses. # the same as {#destination_path} but it can be overridden in subclasses.
# @return [String] # @return [String]
@ -43,13 +46,6 @@ module Middleman
@metadata = { options: {}, locals: {}, page: {} } @metadata = { options: {}, locals: {}, page: {} }
end end
# Set the on-disk source file for this resource
# @return [String]
def source_file
# TODO: Make this work when get_source_file doesn't exist
@source_file || get_source_file
end
# Whether this resource has a template file # Whether this resource has a template file
# @return [Boolean] # @return [Boolean]
def template? def template?
@ -136,7 +132,30 @@ module Middleman
# #
# @return [Boolean] # @return [Boolean]
def binary? def binary?
::Middleman::Util.binary?(source_file) source_file && ::Middleman::Util.binary?(source_file)
end
# Ignore a resource directly, without going through the whole
# ignore filter stuff.
# @return [void]
def ignore!
@ignored = true
end
# Whether the Resource is ignored
# @return [Boolean]
def ignored?
return true if @ignored
# Ignore based on the source path (without template extensions)
return true if @app.sitemap.ignored?(path)
# This allows files to be ignored by their source file name (with template extensions)
!self.is_a?(ProxyResource) && @app.sitemap.ignored?(source_file.sub("#{@app.source_dir}/", ''))
end
# The preferred MIME content type for this resource based on extension or metadata
# @return [String] MIME type for this resource
def content_type
options[:content_type] || ::Rack::Mime.mime_type(ext, nil)
end end
end end
end end