From 1fc97d9d7bbe8edb5d54c64d2870bb7d40569e08 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Tue, 31 Jan 2012 22:15:45 -0800 Subject: [PATCH 1/7] A minor simplification of Sitemap::Store#path - it can no longer take a block --- middleman-core/lib/middleman-core/sitemap/store.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index 9071f1b6..18987019 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -47,18 +47,16 @@ module Middleman::Sitemap # @param [String] target # @return [void] def proxy(path, target) - page(path) { proxy_to(target.sub(%r{^/}, "")) } + page(path).proxy_to(target.sub(%r{^/}, "")) app.cache.remove(:proxied_paths) end # Get a page instance for a given path # @param [String] path # @return [Middleman::Sitemap::Page] - def page(path, &block) + def page(path) path = path.sub(/^\//, "").gsub("%20", " ") - @pages[path] = ::Middleman::Sitemap::Page.new(self, path) unless @pages.has_key?(path) - @pages[path].instance_exec(&block) if block_given? - @pages[path] + @pages.fetch(path) { @pages[path] = ::Middleman::Sitemap::Page.new(self, path) } end # Loop over known pages From 2eec7e11baee0a8e800a7cdb726718a18a2f2b30 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Tue, 31 Jan 2012 22:38:39 -0800 Subject: [PATCH 2/7] Refactor protected method normalize_path out of Sitemap::Store --- .../lib/middleman-core/sitemap/store.rb | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index 18987019..8ff847b8 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -22,7 +22,7 @@ module Middleman::Sitemap # @param [String] path # @return [Boolean] def exists?(path) - @pages.has_key?(path.sub(/^\//, "")) + @pages.has_key?(normalize_path(path)) end # Ignore a path or add an ignore callback @@ -30,10 +30,10 @@ module Middleman::Sitemap # @return [void] def ignore(path=nil, &block) if !path.nil? && path.include?("*") - path_clean = path.sub(/^\//, "") + path_clean = normalize_path(path) @ignored_globs << path_clean unless @ignored_globs.include?(path_clean) elsif path.is_a? String - path_clean = path.sub(/^\//, "") + path_clean = normalize_path(path) @ignored_paths << path_clean unless @ignored_paths.include?(path_clean) elsif path.is_a? Regexp @ignored_regexes << path unless @ignored_regexes.include?(path) @@ -47,7 +47,7 @@ module Middleman::Sitemap # @param [String] target # @return [void] def proxy(path, target) - page(path).proxy_to(target.sub(%r{^/}, "")) + page(path).proxy_to(normalize_path(target)) app.cache.remove(:proxied_paths) end @@ -55,13 +55,13 @@ module Middleman::Sitemap # @param [String] path # @return [Middleman::Sitemap::Page] def page(path) - path = path.sub(/^\//, "").gsub("%20", " ") + path = normalize_path(path) @pages.fetch(path) { @pages[path] = ::Middleman::Sitemap::Page.new(self, path) } end # Loop over known pages # @return [void] - def each(&block) + def each @pages.each do |k, v| yield k, v end @@ -77,9 +77,7 @@ module Middleman::Sitemap # @param [String] path # @return [Boolean] def ignored?(path) - path_clean = path.sub(/^\//, "") - - # $stderr.puts path_clean, @ignored_globs, @ignored_paths + path_clean = normalize_path(path) return true if @ignored_paths.include?(path_clean) return true if @ignored_globs.any? { |g| File.fnmatch(g, path_clean) } @@ -99,7 +97,7 @@ module Middleman::Sitemap # @param [String] path # @return [Boolean] def generic?(path) - generic_paths.include?(path.sub(/^\//, "")) + generic_paths.include?(normalize_path(path)) end # Get a list of generic paths @@ -114,7 +112,7 @@ module Middleman::Sitemap # @param [String] path # @return [Boolean] def proxied?(path) - proxied_paths.include?(path.sub(/^\//, "")) + proxied_paths.include?(normalize_path(path)) end # Get a list of proxied paths @@ -132,7 +130,7 @@ module Middleman::Sitemap path = file_to_path(file) return false unless path - path = path.sub(/^\//, "") + path = normalize_path(path) if @pages.has_key?(path) page(path).delete() @pages.delete(path) @@ -187,7 +185,7 @@ module Middleman::Sitemap # Get a path without templating extensions # @param [String] file - # @param [String] + # @return [String] def extensionless_path(file) app.cache.fetch(:extensionless_path, file) do path = file.dup @@ -204,5 +202,12 @@ module Middleman::Sitemap path end end + + # Normalize a path to not include a leading slash + # @param [String] path + # @return [String] + def normalize_path(path) + path.sub(/^\//, "").gsub("%20", " ") + end end end From a41bf57f2d2a4a3bde22acba4e7004999a501230 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Tue, 31 Jan 2012 22:57:55 -0800 Subject: [PATCH 3/7] Clarify in the documentation what "path" means for Sitemap::Store and Sitemap::Page --- middleman-core/lib/middleman-core/sitemap/page.rb | 4 +++- middleman-core/lib/middleman-core/sitemap/store.rb | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/middleman-core/lib/middleman-core/sitemap/page.rb b/middleman-core/lib/middleman-core/sitemap/page.rb index 8a8fab81..33af034e 100644 --- a/middleman-core/lib/middleman-core/sitemap/page.rb +++ b/middleman-core/lib/middleman-core/sitemap/page.rb @@ -6,6 +6,8 @@ module Middleman::Sitemap # @return [Middleman::Sitemap::Store] attr_accessor :store + # The source path of this page (relative to the source directory, + # without template extensions) # @return [String] attr_accessor :path @@ -263,4 +265,4 @@ module Middleman::Sitemap store.app end end -end \ No newline at end of file +end diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index 8ff847b8..f7f96abf 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -2,6 +2,11 @@ module Middleman::Sitemap # The Store class + # + # The Store manages a collection of Page objects, which represent + # individual items in the sitemap. Pages are indexed by "source path", + # which is the path relative to the source directory, minus any template + # extensions. All "path" parameters used in this class are source paths. class Store # @return [Middleman::Base] @@ -26,7 +31,7 @@ module Middleman::Sitemap end # Ignore a path or add an ignore callback - # @param [String, Regexp] path + # @param [String, Regexp] path, path glob expression, or path regex # @return [void] def ignore(path=nil, &block) if !path.nil? && path.include?("*") @@ -60,6 +65,7 @@ module Middleman::Sitemap end # Loop over known pages + # @yield [path, page] # @return [void] def each @pages.each do |k, v| From 4ce6913baf41f4d068a275b372c58d02df8a085b Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Tue, 31 Jan 2012 23:43:05 -0800 Subject: [PATCH 4/7] The beginnings of refactoring page rerouting. Added methods to Sitemap::Store and Sitemap::Page to collect and execute reroute callbacks, and rework builder to use page methods (simplifying it greatly in the process). All tests that don't involve directory indexes pass - next step is to make the directory index extension register its callbacks with Sitemap::Store#reroute. --- .../lib/middleman-core/cli/build.rb | 31 +++++++++---------- .../middleman-core/core_extensions/builder.rb | 11 ++++--- .../extensions/directory_indexes.rb | 7 ++--- .../lib/middleman-core/sitemap/page.rb | 9 ++++++ .../lib/middleman-core/sitemap/store.rb | 14 +++++++++ 5 files changed, 45 insertions(+), 27 deletions(-) diff --git a/middleman-core/lib/middleman-core/cli/build.rb b/middleman-core/lib/middleman-core/cli/build.rb index 1f28ae5c..45d61c35 100644 --- a/middleman-core/lib/middleman-core/cli/build.rb +++ b/middleman-core/lib/middleman-core/cli/build.rb @@ -95,25 +95,17 @@ module Middleman::Cli # Ignore following method desc "", "", :hide => true - # Render a template to a file. + # Render a page to a file. # - # @param [String] source - # @param [String] destination - # @param [Hash] config - # @return [String] the actual destination file path that was created - def tilt_template(source, destination, config={}) + # @param [Middleman::Sitemap::Page] page + # @return [void] + def tilt_template(page) build_dir = self.class.shared_instance.build_dir - request_path = destination.sub(/^#{build_dir}/, "") - config[:force] = true begin - destination, request_path = self.class.shared_instance.reroute_builder(destination, request_path) - - response = self.class.shared_rack.get(request_path.gsub(/\s/, "%20")) - - create_file(destination, response.body, config) - - destination + response = self.class.shared_rack.get(page.request_path.gsub(/\s/, "%20")) + output_file = File.join(self.class.shared_instance.build_dir, page.destination_path) + create_file(output_file, response.body, { :force => true }) rescue say_status :error, destination, :red abort @@ -221,7 +213,10 @@ module Middleman::Cli # Loop over all the paths and build them. paths.each do |path| + puts "SOURCE: #{path}" + file_source = path + # TODO: OMG use pathnames? file_destination = File.join(given_destination, file_source.gsub(source, '.')) file_destination.gsub!('/./', '/') @@ -231,11 +226,13 @@ module Middleman::Cli next end + page = @app.sitemap.page(file_source) + next if @config[:glob] && !File.fnmatch(@config[:glob], file_source) - file_destination = base.tilt_template(file_source, file_destination) + base.tilt_template(page) - @cleaning_queue.delete(Pathname.new(file_destination).realpath) if cleaning? + @cleaning_queue.delete(Pathname.new(page.destination_path).realpath) if cleaning? end end end diff --git a/middleman-core/lib/middleman-core/core_extensions/builder.rb b/middleman-core/lib/middleman-core/core_extensions/builder.rb index 5ba2b160..7f67222b 100644 --- a/middleman-core/lib/middleman-core/core_extensions/builder.rb +++ b/middleman-core/lib/middleman-core/core_extensions/builder.rb @@ -16,7 +16,8 @@ module Middleman::CoreExtensions::Builder # Build Class Methods module ClassMethods # Get a list of callbacks which can modify a files build path - # + # Each callback takes a destination path and a request path and + # returns a new destination path, or false if it doesn't want to reroute. # @return [Array] def build_reroute(&block) @build_rerouters ||= [] @@ -29,14 +30,14 @@ module Middleman::CoreExtensions::Builder module InstanceMethods # Run through callbacks and get the new values # - # @param [String] destination The current destination of the built file - # @param [String] request_path The current request path of the file - # @return [Array] The new values + # @param [String] destination The current destination path of the built file + # @param [String] request_path The request path of the file + # @return [String] The new destination path def reroute_builder(destination, request_path) result = [destination, request_path] build_reroute.each do |block| - output = instance_exec(destination, request_path, &block) + output = block.call(destination, request_path) if output result = output break diff --git a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb index 1c8ea2df..52264097 100644 --- a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb +++ b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb @@ -74,10 +74,7 @@ module Middleman::Extensions elsif frontmatter_ignore false else - [ - destination.sub(/#{index_ext.gsub(".", "\\.")}$/, new_index_path), - request_path - ] + destination.sub(/#{index_ext.gsub(".", "\\.")}$/, new_index_path), end end end @@ -110,4 +107,4 @@ module Middleman::Extensions # Register the extension register :directory_indexes, DirectoryIndexes -end \ No newline at end of file +end diff --git a/middleman-core/lib/middleman-core/sitemap/page.rb b/middleman-core/lib/middleman-core/sitemap/page.rb index 33af034e..2fc1c9b2 100644 --- a/middleman-core/lib/middleman-core/sitemap/page.rb +++ b/middleman-core/lib/middleman-core/sitemap/page.rb @@ -187,6 +187,15 @@ module Middleman::Sitemap def relative_path self.source_file ? self.source_file.sub(app.source_dir, '') : nil end + + # Get the destination path, relative to the build directory. + # This path can be affected by proxy callbacks. + # @return [String] + def destination_path + store.reroute_callbacks.inject(self.path) do |destination, callback| + callback.call(destination) + end + end # This page's frontmatter # @return [Hash, nil] diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index f7f96abf..f7471916 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -21,6 +21,7 @@ module Middleman::Sitemap @ignored_globs = [] @ignored_regexes = [] @ignored_callbacks = [] + @reroute_callbacks = [] end # Check to see if we know about a specific path @@ -47,6 +48,19 @@ module Middleman::Sitemap end end + # Add a callback that will be run with each page's destination path + # and can produce a new destination path or pass through the old one. + # @return [void] + def reroute(&block) + @reroute_callbacks << block if block_given? + end + + # The list of reroute callbacks + # @return [Array] + def reroute_callbacks + @reroute_callbacks + end + # Setup a proxy from a path to a target # @param [String] path # @param [String] target From ca1f3ddf833df43919170dce3945b663e5514d54 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Thu, 2 Feb 2012 21:47:54 -0800 Subject: [PATCH 5/7] Directory indexes now work during build, with the exception of .htaccess files. --- .../lib/middleman-core/cli/build.rb | 4 +- .../middleman-core/core_extensions/routing.rb | 4 +- .../middleman-core/core_extensions/sitemap.rb | 6 +-- .../extensions/directory_indexes.rb | 49 ++++++++++--------- .../lib/middleman-core/sitemap/page.rb | 2 +- 5 files changed, 34 insertions(+), 31 deletions(-) diff --git a/middleman-core/lib/middleman-core/cli/build.rb b/middleman-core/lib/middleman-core/cli/build.rb index 45d61c35..c3bae1d2 100644 --- a/middleman-core/lib/middleman-core/cli/build.rb +++ b/middleman-core/lib/middleman-core/cli/build.rb @@ -101,10 +101,10 @@ module Middleman::Cli # @return [void] def tilt_template(page) build_dir = self.class.shared_instance.build_dir + output_file = File.join(self.class.shared_instance.build_dir, page.output_file_path) begin response = self.class.shared_rack.get(page.request_path.gsub(/\s/, "%20")) - output_file = File.join(self.class.shared_instance.build_dir, page.destination_path) create_file(output_file, response.body, { :force => true }) rescue say_status :error, destination, :red @@ -228,6 +228,8 @@ module Middleman::Cli page = @app.sitemap.page(file_source) + puts "DEST: #{page.destination_path}" + next if @config[:glob] && !File.fnmatch(@config[:glob], file_source) base.tilt_template(page) diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index d5ec1808..6be37409 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -64,7 +64,7 @@ module Middleman::CoreExtensions::Routing # Setup proxy if opts.has_key?(:proxy) - reroute(url, opts[:proxy]) + proxy(url, opts[:proxy]) if opts.has_key?(:ignore) && opts[:ignore] ignore(opts[:proxy]) @@ -89,4 +89,4 @@ module Middleman::CoreExtensions::Routing end end end -end \ No newline at end of file +end diff --git a/middleman-core/lib/middleman-core/core_extensions/sitemap.rb b/middleman-core/lib/middleman-core/core_extensions/sitemap.rb index a2c7e6b9..4366d976 100644 --- a/middleman-core/lib/middleman-core/core_extensions/sitemap.rb +++ b/middleman-core/lib/middleman-core/core_extensions/sitemap.rb @@ -74,10 +74,10 @@ module Middleman::CoreExtensions::Sitemap # @param [String] url # @param [String] target # @return [void] - def reroute(*args) + def proxy(*args) sitemap.proxy(*args) end - + # Register a handler to provide metadata on a file path # @param [Regexp] matcher # @return [Array>] @@ -96,4 +96,4 @@ module Middleman::CoreExtensions::Sitemap @_provides_metadata_for_path end end -end \ No newline at end of file +end diff --git a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb index 52264097..aa1d8e5f 100644 --- a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb +++ b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb @@ -12,6 +12,8 @@ module Middleman::Extensions # Include methods app.send :include, InstanceMethods + # TODO: unify these + # Before requests app.before do prefix = @original_path.sub(/\/$/, "") @@ -51,41 +53,40 @@ module Middleman::Extensions end end - # Basically does the same as above, but in build mode - app.build_reroute do |destination, request_path| - index_ext = File.extname(index_file) - new_index_path = "/#{index_file}" - frontmatter_ignore = false + app.after_configuration do + # Basically does the same as above, but in build mode + sitemap.reroute do |destination, page| + new_index_path = "/#{index_file}" + frontmatter_ignore = false - # Check for file and frontmatter - if sitemap.exists?(request_path) - p = sitemap.page(request_path) - d = p.data - if !d.nil? + # Check for file and frontmatter + d = page.data + if !page.data.nil? frontmatter_ignore = d.has_key?("directory_index") && d["directory_index"] == false end - end - # Only reroute if not ignored - if ignored_directory_indexes.include?(request_path) - false - elsif request_path =~ /#{new_index_path}$/ - false - elsif frontmatter_ignore - false - else - destination.sub(/#{index_ext.gsub(".", "\\.")}$/, new_index_path), + # Only reroute if not ignored + request_path = page.request_path + if ignored_directory_indexes.include? page + destination + elsif request_path.end_with? new_index_path + destination + elsif frontmatter_ignore + destination + else + index_ext = File.extname(index_file) + destination.chomp(File.extname(index_file)) + new_index_path + end end end end - + alias :included :registered end - # Directory indexes instance methods module InstanceMethods # A list of pages which will not use directory indexes - # @return [Array] + # @return [Array] def ignored_directory_indexes @_ignored_directory_indexes ||= [] end @@ -97,7 +98,7 @@ module Middleman::Extensions # @return [void] def page(url, options={}, &block) if options.has_key?(:directory_index) && !options["directory_index"] - ignored_directory_indexes << url + ignored_directory_indexes << sitemap.page(url) else super end diff --git a/middleman-core/lib/middleman-core/sitemap/page.rb b/middleman-core/lib/middleman-core/sitemap/page.rb index 2fc1c9b2..48d20c24 100644 --- a/middleman-core/lib/middleman-core/sitemap/page.rb +++ b/middleman-core/lib/middleman-core/sitemap/page.rb @@ -193,7 +193,7 @@ module Middleman::Sitemap # @return [String] def destination_path store.reroute_callbacks.inject(self.path) do |destination, callback| - callback.call(destination) + callback.call(destination, self) end end From e27e0cdd446c6e2426b4ea07d9ca2538632d7a93 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 3 Feb 2012 00:14:49 -0800 Subject: [PATCH 6/7] Directory indexes work completely now, in preview and with dotfiles. --- middleman-core/lib/middleman-core/base.rb | 2 +- .../lib/middleman-core/cli/build.rb | 30 +++++++------------ .../extensions/directory_indexes.rb | 18 +++++++---- .../lib/middleman-core/sitemap/store.rb | 4 ++- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/middleman-core/lib/middleman-core/base.rb b/middleman-core/lib/middleman-core/base.rb index 8c9d02a4..e7269e0c 100644 --- a/middleman-core/lib/middleman-core/base.rb +++ b/middleman-core/lib/middleman-core/base.rb @@ -494,4 +494,4 @@ protected end res['Content-Type'] = mime_type end -end \ No newline at end of file +end diff --git a/middleman-core/lib/middleman-core/cli/build.rb b/middleman-core/lib/middleman-core/cli/build.rb index c3bae1d2..95ec6d00 100644 --- a/middleman-core/lib/middleman-core/cli/build.rb +++ b/middleman-core/lib/middleman-core/cli/build.rb @@ -101,13 +101,14 @@ module Middleman::Cli # @return [void] def tilt_template(page) build_dir = self.class.shared_instance.build_dir - output_file = File.join(self.class.shared_instance.build_dir, page.output_file_path) + output_file = File.join(self.class.shared_instance.build_dir, page.destination_path) begin response = self.class.shared_rack.get(page.request_path.gsub(/\s/, "%20")) create_file(output_file, response.body, { :force => true }) rescue - say_status :error, destination, :red + say_status :error, output_file, :red + puts $! abort end end @@ -201,6 +202,8 @@ module Middleman::Cli # Sort paths to be built by the above order. This is primarily so Compass can # find files in the build folder when it needs to generate sprites for the # css files + + # TODO: deal with pages, not paths paths = @app.sitemap.all_paths.sort do |a, b| a_ext = File.extname(a) b_ext = File.extname(b) @@ -213,28 +216,15 @@ module Middleman::Cli # Loop over all the paths and build them. paths.each do |path| - puts "SOURCE: #{path}" + page = @app.sitemap.page(path) - file_source = path - # TODO: OMG use pathnames? - file_destination = File.join(given_destination, file_source.gsub(source, '.')) - file_destination.gsub!('/./', '/') - - if @app.sitemap.proxied?(file_source) - file_source = @app.sitemap.page(file_source).proxied_to - elsif @app.sitemap.page(file_source).ignored? - next - end - - page = @app.sitemap.page(file_source) - - puts "DEST: #{page.destination_path}" - - next if @config[:glob] && !File.fnmatch(@config[:glob], file_source) + next if page.ignored? + next if @config[:glob] && !File.fnmatch(@config[:glob], path) base.tilt_template(page) - @cleaning_queue.delete(Pathname.new(page.destination_path).realpath) if cleaning? + output_path = File.join(@destination, page.destination_path) + @cleaning_queue.delete(Pathname.new(output_path).realpath) if cleaning? end end end diff --git a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb index aa1d8e5f..963e89d7 100644 --- a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb +++ b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb @@ -12,14 +12,15 @@ module Middleman::Extensions # Include methods app.send :include, InstanceMethods - # TODO: unify these + # TODO: unify these by replacing the "before" thing with a + # lookup by destination_path # Before requests app.before do prefix = @original_path.sub(/\/$/, "") indexed_path = prefix + "/" + index_file extensioned_path = prefix + File.extname(index_file) - + is_ignored = false fm_ignored = false @@ -36,13 +37,15 @@ module Middleman::Extensions end else # Otherwise check this extension for list of ignored indexes - is_ignored = ignored_directory_indexes.include?(extensioned_path) + if sitemap.exists?(extensioned_path) + is_ignored = ignored_directory_indexes.include?(sitemap.page(extensioned_path)) + end end # If we're going to remap to a directory index if !sitemap.exists?(indexed_path) && !is_ignored && !fm_ignored parts = @original_path.split("/") - last_part = parts.last + last_part = parts.last || '' last_part_ext = File.extname(last_part) # Change the request @@ -65,16 +68,19 @@ module Middleman::Extensions frontmatter_ignore = d.has_key?("directory_index") && d["directory_index"] == false end + index_ext = File.extname(index_file) + # Only reroute if not ignored request_path = page.request_path if ignored_directory_indexes.include? page destination - elsif request_path.end_with? new_index_path + elsif request_path == index_file || request_path.end_with?(new_index_path) destination elsif frontmatter_ignore destination + elsif index_ext != File.extname(request_path) + destination else - index_ext = File.extname(index_file) destination.chomp(File.extname(index_file)) + new_index_path end end diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index f7471916..e69cfd3c 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -103,7 +103,9 @@ module Middleman::Sitemap return true if @ignored_globs.any? { |g| File.fnmatch(g, path_clean) } return true if @ignored_regexes.any? { |r| r.match(path_clean) } return true if @ignored_callbacks.any? { |b| b.call(path_clean) } - + + # TODO: We should also check ignored_sitemap_matchers here + false end From e136fab77ca0a1cd204f04bc574878c01618c226 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 4 Feb 2012 23:07:02 -0800 Subject: [PATCH 7/7] Use a page_by_destination lookup to make rerouting work both ways, in build and during preview server. --- .../features/wildcard_page_helper.feature | 2 +- middleman-core/lib/middleman-core/base.rb | 12 ++--- .../extensions/directory_indexes.rb | 52 ++----------------- .../lib/middleman-core/sitemap/page.rb | 5 +- .../lib/middleman-core/sitemap/store.rb | 9 +++- 5 files changed, 22 insertions(+), 58 deletions(-) diff --git a/middleman-core/features/wildcard_page_helper.feature b/middleman-core/features/wildcard_page_helper.feature index baa75556..5ac7a25e 100644 --- a/middleman-core/features/wildcard_page_helper.feature +++ b/middleman-core/features/wildcard_page_helper.feature @@ -15,5 +15,5 @@ Feature: Wildcards in Page helper Then I should see "Normal Layout" When I go to "/admin/" Then I should see "Admin Layout" - When I go to "/admin/page.html" + When I go to "/admin/page/" Then I should see "Admin Layout" \ No newline at end of file diff --git a/middleman-core/lib/middleman-core/base.rb b/middleman-core/lib/middleman-core/base.rb index e7269e0c..7ab77383 100644 --- a/middleman-core/lib/middleman-core/base.rb +++ b/middleman-core/lib/middleman-core/base.rb @@ -370,13 +370,13 @@ class Middleman::Base # Run before callbacks run_hook :before - - # Return 404 if not in sitemap - return not_found unless sitemap.exists?(@request_path) - + # Get the page object for this path - sitemap_page = sitemap.page(@request_path) - + sitemap_page = sitemap.page_by_destination(@request_path) + + # Return 404 if not in sitemap + return not_found unless sitemap_page + # Return 404 if this path is specifically ignored return not_found if sitemap_page.ignored? diff --git a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb index 963e89d7..4c591c9d 100644 --- a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb +++ b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb @@ -12,52 +12,8 @@ module Middleman::Extensions # Include methods app.send :include, InstanceMethods - # TODO: unify these by replacing the "before" thing with a - # lookup by destination_path - - # Before requests - app.before do - prefix = @original_path.sub(/\/$/, "") - indexed_path = prefix + "/" + index_file - extensioned_path = prefix + File.extname(index_file) - - is_ignored = false - fm_ignored = false - - # If the sitemap knows about the path - if sitemap.exists?(@original_path) - # Inspect frontmatter - d = sitemap.page(@original_path).data - - # Allow the frontmatter to ignore a directory index - if !d.nil? && d.has_key?("directory_index") && d["directory_index"] == false - fm_ignored = true - else - next - end - else - # Otherwise check this extension for list of ignored indexes - if sitemap.exists?(extensioned_path) - is_ignored = ignored_directory_indexes.include?(sitemap.page(extensioned_path)) - end - end - - # If we're going to remap to a directory index - if !sitemap.exists?(indexed_path) && !is_ignored && !fm_ignored - parts = @original_path.split("/") - last_part = parts.last || '' - last_part_ext = File.extname(last_part) - - # Change the request - if last_part_ext.blank? - # This is a folder, redirect to index - @request_path = extensioned_path - end - end - end - app.after_configuration do - # Basically does the same as above, but in build mode + # Register a reroute transform that turns regular paths into indexed paths sitemap.reroute do |destination, page| new_index_path = "/#{index_file}" frontmatter_ignore = false @@ -71,14 +27,14 @@ module Middleman::Extensions index_ext = File.extname(index_file) # Only reroute if not ignored - request_path = page.request_path + path = page.path if ignored_directory_indexes.include? page destination - elsif request_path == index_file || request_path.end_with?(new_index_path) + elsif path == index_file || path.end_with?(new_index_path) destination elsif frontmatter_ignore destination - elsif index_ext != File.extname(request_path) + elsif index_ext != File.extname(path) destination else destination.chomp(File.extname(index_file)) + new_index_path diff --git a/middleman-core/lib/middleman-core/sitemap/page.rb b/middleman-core/lib/middleman-core/sitemap/page.rb index 48d20c24..b14faca7 100644 --- a/middleman-core/lib/middleman-core/sitemap/page.rb +++ b/middleman-core/lib/middleman-core/sitemap/page.rb @@ -43,9 +43,9 @@ module Middleman::Sitemap # @return [String] def request_path if proxy? - store.page(proxied_to).path + store.page(proxied_to).destination_path else - path + destination_path end end @@ -192,6 +192,7 @@ module Middleman::Sitemap # This path can be affected by proxy callbacks. # @return [String] def destination_path + # TODO: memoize this value store.reroute_callbacks.inject(self.path) do |destination, callback| callback.call(destination, self) end diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index e69cfd3c..b14dac67 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -77,6 +77,13 @@ module Middleman::Sitemap path = normalize_path(path) @pages.fetch(path) { @pages[path] = ::Middleman::Sitemap::Page.new(self, path) } end + + # Find a page given its destination path + def page_by_destination(destination_path) + # TODO: memoize this + destination_path = normalize_path(destination_path) + @pages.values.find {|p| p.destination_path == destination_path } + end # Loop over known pages # @yield [path, page] @@ -86,7 +93,7 @@ module Middleman::Sitemap yield k, v end end - + # Get all known paths # @return [Array] def all_paths