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.

This commit is contained in:
Ben Hollis 2012-01-31 23:43:05 -08:00
parent a41bf57f2d
commit 4ce6913baf
5 changed files with 45 additions and 27 deletions

View file

@ -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

View file

@ -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<Proc>]
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<String>] 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

View file

@ -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
end

View file

@ -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]

View file

@ -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<Proc>]
def reroute_callbacks
@reroute_callbacks
end
# Setup a proxy from a path to a target
# @param [String] path
# @param [String] target