From c473181167e3cbcfbfb08c100334b1f451c01814 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 7 Jan 2012 17:21:26 -0800 Subject: [PATCH] frontmatter can control whether a page is ignored --- .../frontmatter_page_settings.feature | 8 +- .../core_extensions/front_matter.rb | 73 +++++++++++++++++-- .../middleman-core/core_extensions/sitemap.rb | 4 +- 3 files changed, 73 insertions(+), 12 deletions(-) diff --git a/middleman-core/features/frontmatter_page_settings.feature b/middleman-core/features/frontmatter_page_settings.feature index b2c7667f..c288a5a4 100644 --- a/middleman-core/features/frontmatter_page_settings.feature +++ b/middleman-core/features/frontmatter_page_settings.feature @@ -2,9 +2,9 @@ Feature: Setting page settings through frontmatter Scenario: Setting layout, ignoring, and disabling directory indexes through frontmatter Given a successfully built app at "frontmatter-settings-app" Then the following files should exist: - | build/proxied/index.html | - | build/no_index.html | + | build/proxied/index.html | + | build/no_index.html | And the file "build/alternate_layout/index.html" should contain "Alternate layout" And the following files should not exist: - | build/ignored/index.html | - | build/no_index/index.html | + | build/ignored/index.html | + | build/no_index/index.html | \ No newline at end of file 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 199e9bf7..e2bdff5f 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -1,8 +1,16 @@ +# Parsing YAML frontmatter require "yaml" + +# Looking up Tilt extensions require "tilt" +# Frontmatter namespace module Middleman::CoreExtensions::FrontMatter + + # Setup extension class << self + + # Once registered def registered(app) app.set :frontmatter_extensions, %w(.htm .html .php) app.extend ClassMethods @@ -12,7 +20,12 @@ module Middleman::CoreExtensions::FrontMatter alias :included :registered end + # Frontmatter class methods module ClassMethods + + # Register callback on frontmatter updates + # @param [Regexp] matcher + # @return [Array>] def frontmatter_changed(matcher=nil, &block) @_frontmatter_changed ||= [] @_frontmatter_changed << [block, matcher] if block_given? @@ -20,22 +33,25 @@ module Middleman::CoreExtensions::FrontMatter end end + # Frontmatter instance methods module InstanceMethods + + # Override init def initialize super exts = frontmatter_extensions.join("|").gsub(".", "\.") - static_path = source_dir.sub(self.root, "").sub(/^\//, "").sub(/\/$/, "") + "/" + static_path = source_dir.sub(root, "").sub(/^\//, "").sub(/\/$/, "") + "/" matcher = %r{#{static_path}.*(#{exts})} - self.files.changed matcher do |file| - self.frontmatter_extension.touch_file(file) + files.changed matcher do |file| + frontmatter_extension.touch_file(file) end - self.files.deleted matcher do |file| - self.frontmatter_extension.remove_file(file) + files.deleted matcher do |file| + frontmatter_extension.remove_file(file) end provides_metadata matcher do |path| @@ -56,6 +72,9 @@ module Middleman::CoreExtensions::FrontMatter end end + # Notify callbacks that the frontmatter changed + # @param [String] path + # @return [void] def frontmatter_did_change(path) frontmatter_changed.each do |callback, matcher| next if path.match(%r{^#{build_dir}/}) @@ -64,26 +83,58 @@ module Middleman::CoreExtensions::FrontMatter end end + # Get the frontmatter object + # @return [Middleman::CoreExtensions::FrontMatter::FrontMatter] def frontmatter_extension @_frontmatter_extension ||= FrontMatter.new(self) end + # Get the frontmatter for the given params + # @param [String] path + # @return [Hash, nil] def frontmatter(*args) frontmatter_extension.data(*args) end end + # Core Frontmatter class class FrontMatter + + # Initialize frontmatter with current app + # @param [Middleman::Base] app def initialize(app) @app = app @source = File.expand_path(@app.source, @app.root) @local_data = {} + + # Setup ignore callback + @app.ignore do |path| + p = @app.sitemap.page(path) + file_path = p.source_file.sub(@app.source_dir, "") + + if has_data?(file_path) + d = data(file_path) + if d && d[0] + d[0].has_key?("ignored") && d[0]["ignored"] == true + else + false + end + else + false + end + end end + # Whether the frontmatter knows about a path + # @param [String] path + # @return [Boolean] def has_data?(path) @local_data.has_key?(path.to_s) end + # Update frontmatter if a file changes + # @param [String] file + # @return [void] def touch_file(file) extension = File.extname(file).sub(/\./, "") return unless ::Tilt.mappings.has_key?(extension) @@ -104,16 +155,23 @@ module Middleman::CoreExtensions::FrontMatter end end + # Update frontmatter if a file is delted + # @param [String] file + # @return [void] def remove_file(file) file = File.expand_path(file, @app.root) file = file.sub(@app.source_dir, "") - # @app.logger.debug :frontmatter_remove, Time.now, file if @app.logging? if @local_data.has_key?(file) + path = File.join(@app.source_dir, file) + @app.cache.remove(:raw_template, path) @local_data.delete(file) end end + # Get the frontmatter for a given path + # @param [String] path + # @return [Hash, nil] def data(path) if @local_data.has_key?(path.to_s) @local_data[path.to_s] @@ -123,6 +181,9 @@ module Middleman::CoreExtensions::FrontMatter end private + # Parse frontmatter out of a string + # @param [String] content + # @return [Array] def parse_front_matter(content) yaml_regex = /^(---\s*\n.*?\n?)^(---\s*$\n?)/m if content =~ yaml_regex diff --git a/middleman-core/lib/middleman-core/core_extensions/sitemap.rb b/middleman-core/lib/middleman-core/core_extensions/sitemap.rb index 1afb0cf2..0435911c 100644 --- a/middleman-core/lib/middleman-core/core_extensions/sitemap.rb +++ b/middleman-core/lib/middleman-core/core_extensions/sitemap.rb @@ -64,8 +64,8 @@ module Middleman::CoreExtensions::Sitemap # Ignore a path, regex or callback # @param [String, Regexp] # @return [void] - def ignore(*args) - sitemap.ignore(*args) + def ignore(*args, &block) + sitemap.ignore(*args, &block) end # Proxy one path to another