diff --git a/middleman-core/fixtures/frontmatter-neighbor-app/config.rb b/middleman-core/fixtures/frontmatter-neighbor-app/config.rb index e69de29b..50a368eb 100644 --- a/middleman-core/fixtures/frontmatter-neighbor-app/config.rb +++ b/middleman-core/fixtures/frontmatter-neighbor-app/config.rb @@ -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 diff --git a/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb b/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb index a5e8129a..600b96f8 100644 --- a/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb +++ b/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb @@ -2,3 +2,31 @@ proxy 'proxied.html', 'ignored.html' page 'override_layout.html', layout: :alternate 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 diff --git a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb index 712d5d6c..72412398 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -57,10 +57,6 @@ module Middleman::CoreExtensions end end - def after_configuration - app.ignore %r{\.frontmatter$} - end - # Get the template data from a path # @param [String] path # @return [String] @@ -70,16 +66,7 @@ module Middleman::CoreExtensions def data(path) p = normalize_path(path) - @cache[p] ||= begin - 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 + @cache[p] ||= frontmatter_and_content(p) end def clear_data(file) @@ -88,11 +75,43 @@ module Middleman::CoreExtensions file = File.join(app.root, file) prefix = app.source_dir.sub(/\/$/, '') + '/' return unless file.include?(prefix) - path = file.sub(prefix, '').sub(/\.frontmatter$/, '') + path = file.sub(prefix, '') @cache.delete(path) end + # Get the frontmatter and plain content from a file + # @param [String] path + # @return [Array] + 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 # Parse YAML frontmatter out of a string @@ -142,38 +161,6 @@ module Middleman::CoreExtensions [{}, content] end - # Get the frontmatter and plain content from a file - # @param [String] path - # @return [Array] - 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) path.sub(%r{^#{Regexp.escape(app.source_dir)}\/}, '') end diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index b7f4ee52..24539ce0 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -45,8 +45,6 @@ module Middleman options = opts.dup # Default layout - # TODO: This seems wrong - options[:layout] = @app.config[:layout] if options[:layout].nil? metadata = { options: options, locals: options.delete(:locals) || {}, diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/content_type.rb b/middleman-core/lib/middleman-core/sitemap/extensions/content_type.rb deleted file mode 100644 index 23325012..00000000 --- a/middleman-core/lib/middleman-core/sitemap/extensions/content_type.rb +++ /dev/null @@ -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 diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb index 9ca344a2..b77f0e19 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb @@ -12,7 +12,6 @@ module Middleman @ignored_callbacks = [] sitemap.define_singleton_method :ignored?, &method(:ignored?) - ::Middleman::Sitemap::Resource.send :include, IgnoreResourceInstanceMethods end # Ignore a path or add an ignore callback @@ -45,27 +44,6 @@ module Middleman @ignored_callbacks.any? { |b| b.call(path_clean) } 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 diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb index b9abe44e..9acce571 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb @@ -119,8 +119,7 @@ module Middleman resource end - # rubocop:disable AccessorMethodName - def get_source_file + def source_file target_resource.source_file end @@ -130,17 +129,6 @@ module Middleman target_resource.content_type 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 diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb index 3f4dafd1..d6b79045 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb @@ -75,18 +75,9 @@ module Middleman end end - def binary? - false - end - def ignored? false end - - # rubocop:disable AccessorMethodName - def get_source_file - '' - end end end end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb index 4f5a646e..8d555fa6 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb @@ -64,18 +64,9 @@ module Middleman return output.call if output end - def binary? - false - end - def ignored? false end - - # rubocop:disable AccessorMethodName - def get_source_file - '' - end end end end diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index 97b4e832..fdd57b00 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -1,5 +1,5 @@ +require 'rack/mime' require 'middleman-core/sitemap/extensions/traversal' -require 'middleman-core/sitemap/extensions/content_type' require 'middleman-core/file_renderer' require 'middleman-core/template_renderer' @@ -9,7 +9,6 @@ module Middleman # Sitemap Resource class class Resource include Middleman::Sitemap::Extensions::Traversal - include Middleman::Sitemap::Extensions::ContentType # The source path of this resource (relative to the source directory, # without template extensions) @@ -20,6 +19,10 @@ module Middleman # @return [String] 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 same as {#destination_path} but it can be overridden in subclasses. # @return [String] @@ -43,13 +46,6 @@ module Middleman @metadata = { options: {}, locals: {}, page: {} } 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 # @return [Boolean] def template? @@ -136,7 +132,30 @@ module Middleman # # @return [Boolean] 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