allow dynamic file generation. closes #68

This commit is contained in:
Thomas Reynolds 2011-07-23 22:21:52 -07:00
parent 506148ae8a
commit 527fa3160f
6 changed files with 65 additions and 12 deletions

View file

@ -0,0 +1,24 @@
Feature: Dynamic Pages
In order to use a single view to generate multiple output files
Scenario: Checking built folder for content
Given a built test app
Then "fake.html" should exist and include "I am real"
Then "fake/one.html" should exist and include "I am real: one"
Then "fake/two.html" should exist and include "I am real: two"
And cleanup built test app
Scenario: Preview basic proxy
Given the Server is running
When I go to "/fake.html"
Then I should see "I am real"
Scenario: Preview proxy with variable one
Given the Server is running
When I go to "/fake/one.html"
Then I should see "I am real: one"
Scenario: Preview proxy with variable two
Given the Server is running
When I go to "/fake/two.html"
Then I should see "I am real: two"

View file

@ -1,3 +1,11 @@
page "/fake.html", :proxy => "/real.html", :layout => false
%w(one two).each do |num|
page "/fake/#{num}.html", :proxy => "/real/index.html" do
@num = num
end
end
with_layout false do with_layout false do
page "/inline-css.html" page "/inline-css.html"
page "/inline-js.html" page "/inline-js.html"

View file

@ -0,0 +1 @@
I am real

View file

@ -0,0 +1,5 @@
---
layout: false
---
I am real: <%= @num %>

View file

@ -10,11 +10,11 @@ module Middleman
config = args.last.is_a?(Hash) ? args.pop : {} config = args.last.is_a?(Hash) ? args.pop : {}
destination = args.first || source destination = args.first || source
source = File.expand_path(find_in_source_paths(source.to_s)) # source = File.expand_path(find_in_source_paths(source.to_s))
context = instance_eval('binding') context = instance_eval('binding')
@@rack_test ||= ::Rack::Test::Session.new(::Rack::MockSession.new(SHARED_SERVER)) @@rack_test ||= ::Rack::Test::Session.new(::Rack::MockSession.new(SHARED_SERVER))
create_file destination, nil, config do create_file destination, nil, config do
# The default render just requests the page over Rack and writes the response # The default render just requests the page over Rack and writes the response
request_path = destination.sub(/^#{SHARED_SERVER.build_dir}/, "") request_path = destination.sub(/^#{SHARED_SERVER.build_dir}/, "")
@ -40,7 +40,6 @@ module Middleman
end end
end end
def source_paths def source_paths
@source_paths ||= [ @source_paths ||= [
SHARED_SERVER.root SHARED_SERVER.root
@ -49,6 +48,10 @@ module Middleman
def build_all_files def build_all_files
action Directory.new(self, SHARED_SERVER.views, SHARED_SERVER.build_dir, { :force => true }) action Directory.new(self, SHARED_SERVER.views, SHARED_SERVER.build_dir, { :force => true })
SHARED_SERVER.proxied_paths.each do |url, proxy|
tilt_template(url.gsub(/^\//, "#{SHARED_SERVER.build_dir}/"), { :force => true })
end
end end
@@hooks = {} @@hooks = {}

View file

@ -3,6 +3,8 @@ module Middleman::CoreExtensions::Routing
def registered(app) def registered(app)
app.extend ClassMethods app.extend ClassMethods
app.set :proxied_paths, {}
# Normalize the path and add index if we're looking at a directory # Normalize the path and add index if we're looking at a directory
app.before_processing do app.before_processing do
request.path_info = self.class.path_to_index(request.path) request.path_info = self.class.path_to_index(request.path)
@ -35,23 +37,33 @@ module Middleman::CoreExtensions::Routing
set :layout, old_layout set :layout, old_layout
end end
# The page method allows the layout to be set on a specific path def paths_for_url(url)
# page "/about.html", :layout => false
# page "/", :layout => :homepage_layout
def page(url, options={}, &block)
url = url.gsub(%r{#{settings.index_file}$}, "") url = url.gsub(%r{#{settings.index_file}$}, "")
url = url.gsub(%r{(\/)$}, "") if url.length > 1 url = url.gsub(%r{(\/)$}, "") if url.length > 1
paths = [url] paths = [url]
paths << "#{url}/" if url.length > 1 && url.split("/").last.split('.').length <= 1 paths << "#{url}/" if url.length > 1 && url.split("/").last.split('.').length <= 1
paths << "/#{path_to_index(url)}" paths << "/#{path_to_index(url)}"
paths
options[:layout] = settings.layout if options[:layout].nil? end
# The page method allows the layout to be set on a specific path
# page "/about.html", :layout => false
# page "/", :layout => :homepage_layout
def page(url, options={}, &block)
has_block = block_given? has_block = block_given?
options[:layout] = settings.layout if options[:layout].nil?
paths.each do |p|
if options.has_key?(:proxy)
settings.proxied_paths[url] = options[:proxy]
end
paths_for_url(url).each do |p|
get(p) do get(p) do
if settings.proxied_paths.has_key?(url)
request.path_info = settings.proxied_paths[url]
end
instance_eval(&block) if has_block instance_eval(&block) if has_block
process_request(options) process_request(options)
end end