Implement generic which is a simple way to build a file from Rack
This commit is contained in:
parent
f97c9ffab1
commit
913d2b7049
|
@ -15,6 +15,7 @@
|
||||||
===
|
===
|
||||||
|
|
||||||
* Blocks with different templating languages than their layout now work as expected. #860
|
* Blocks with different templating languages than their layout now work as expected. #860
|
||||||
|
* The `endpoint` method allows the building of Rack-based files or arbitrary content.
|
||||||
|
|
||||||
3.1.0.rc.2
|
3.1.0.rc.2
|
||||||
===
|
===
|
||||||
|
|
|
@ -6,3 +6,62 @@ Feature: Support Rack apps mounted using map
|
||||||
Then I should see "Hello World (Middleman)"
|
Then I should see "Hello World (Middleman)"
|
||||||
When I go to "/sinatra/"
|
When I go to "/sinatra/"
|
||||||
Then I should see "Hello World (Sinatra)"
|
Then I should see "Hello World (Sinatra)"
|
||||||
|
|
||||||
|
Scenario: Built Mounted Rack App at /sinatra
|
||||||
|
Given a successfully built app at "sinatra-app"
|
||||||
|
When I cd to "build"
|
||||||
|
Then the following files should exist:
|
||||||
|
| index.html |
|
||||||
|
Then the following files should not exist:
|
||||||
|
| sinatra/index.html |
|
||||||
|
| sinatra/index2.html |
|
||||||
|
|
||||||
|
Scenario: Static Ruby Endpoints
|
||||||
|
Given a fixture app "sinatra-app"
|
||||||
|
And a file named "config.rb" with:
|
||||||
|
"""
|
||||||
|
endpoint "hello.html" do
|
||||||
|
"world"
|
||||||
|
end
|
||||||
|
"""
|
||||||
|
And the Server is running at "sinatra-app"
|
||||||
|
When I go to "/hello.html"
|
||||||
|
Then I should see "world"
|
||||||
|
|
||||||
|
Scenario: Built Mounted Rack App at /sinatra (including rack endpoints)
|
||||||
|
Given a fixture app "sinatra-app"
|
||||||
|
And a file named "config.rb" with:
|
||||||
|
"""
|
||||||
|
require "sinatra"
|
||||||
|
|
||||||
|
class MySinatra < Sinatra::Base
|
||||||
|
get "/" do
|
||||||
|
"Hello World (Sinatra)"
|
||||||
|
end
|
||||||
|
get "/derp.html" do
|
||||||
|
"De doo"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
map "/sinatra" do
|
||||||
|
run MySinatra
|
||||||
|
end
|
||||||
|
|
||||||
|
configure :build do
|
||||||
|
endpoint "sinatra/index2.html", :path => "/sinatra/"
|
||||||
|
end
|
||||||
|
|
||||||
|
endpoint "dedoo.html", :path => "/sinatra/derp.html"
|
||||||
|
|
||||||
|
endpoint "hello.html" do
|
||||||
|
"world"
|
||||||
|
end
|
||||||
|
"""
|
||||||
|
And a successfully built app at "sinatra-app"
|
||||||
|
When I cd to "build"
|
||||||
|
Then the following files should exist:
|
||||||
|
| index.html |
|
||||||
|
| sinatra/index2.html |
|
||||||
|
| dedoo.html |
|
||||||
|
And the file "sinatra/index2.html" should contain 'Hello World (Sinatra)'
|
||||||
|
And the file "dedoo.html" should contain 'De doo'
|
|
@ -4,6 +4,9 @@ class MySinatra < Sinatra::Base
|
||||||
get "/" do
|
get "/" do
|
||||||
"Hello World (Sinatra)"
|
"Hello World (Sinatra)"
|
||||||
end
|
end
|
||||||
|
get "/derp.html" do
|
||||||
|
"De doo"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
map "/sinatra" do
|
map "/sinatra" do
|
||||||
|
|
|
@ -135,7 +135,7 @@ module Middleman::Cli
|
||||||
FileUtils.cp(resource.source_file, output_file)
|
FileUtils.cp(resource.source_file, output_file)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
response = self.class.shared_rack.get(URI.escape(resource.destination_path))
|
response = self.class.shared_rack.get(URI.escape(resource.request_path))
|
||||||
|
|
||||||
if response.status == 200
|
if response.status == 200
|
||||||
create_file(output_file, binary_encode(response.body))
|
create_file(output_file, binary_encode(response.body))
|
||||||
|
|
|
@ -2,6 +2,7 @@ require "middleman-core/sitemap/store"
|
||||||
require "middleman-core/sitemap/resource"
|
require "middleman-core/sitemap/resource"
|
||||||
|
|
||||||
require "middleman-core/sitemap/extensions/on_disk"
|
require "middleman-core/sitemap/extensions/on_disk"
|
||||||
|
require "middleman-core/sitemap/extensions/request_endpoints"
|
||||||
require "middleman-core/sitemap/extensions/proxies"
|
require "middleman-core/sitemap/extensions/proxies"
|
||||||
require "middleman-core/sitemap/extensions/ignores"
|
require "middleman-core/sitemap/extensions/ignores"
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ module Middleman
|
||||||
# Once registered
|
# Once registered
|
||||||
def registered(app)
|
def registered(app)
|
||||||
|
|
||||||
|
app.register Middleman::Sitemap::Extensions::RequestEndpoints
|
||||||
app.register Middleman::Sitemap::Extensions::Proxies
|
app.register Middleman::Sitemap::Extensions::Proxies
|
||||||
app.register Middleman::Sitemap::Extensions::Ignores
|
app.register Middleman::Sitemap::Extensions::Ignores
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
module Middleman
|
||||||
|
|
||||||
|
module Sitemap
|
||||||
|
|
||||||
|
module Extensions
|
||||||
|
|
||||||
|
module RequestEndpoints
|
||||||
|
|
||||||
|
# Setup extension
|
||||||
|
class << self
|
||||||
|
|
||||||
|
# Once registered
|
||||||
|
def registered(app)
|
||||||
|
# ::Middleman::Sitemap::Resource.send :include, ResourceInstanceMethods
|
||||||
|
|
||||||
|
# Include methods
|
||||||
|
app.send :include, InstanceMethods
|
||||||
|
end
|
||||||
|
|
||||||
|
alias :included :registered
|
||||||
|
end
|
||||||
|
|
||||||
|
# module ResourceInstanceMethods
|
||||||
|
# # Whether this page is a proxy
|
||||||
|
# # @return [Boolean]
|
||||||
|
# def proxy?
|
||||||
|
# !!@proxied_to
|
||||||
|
# end
|
||||||
|
|
||||||
|
# # Set this page to proxy to a target path
|
||||||
|
# # @param [String] target
|
||||||
|
# # @return [void]
|
||||||
|
# def proxy_to(target)
|
||||||
|
# target = ::Middleman::Util.normalize_path(target)
|
||||||
|
# raise "You can't proxy #{path} to itself!" if target == path
|
||||||
|
# @proxied_to = target
|
||||||
|
# end
|
||||||
|
|
||||||
|
# # The path of the page this page is proxied to, or nil if it's not proxied.
|
||||||
|
# # @return [String]
|
||||||
|
# def proxied_to
|
||||||
|
# @proxied_to
|
||||||
|
# end
|
||||||
|
|
||||||
|
# # The resource for the page this page is proxied to. Throws an exception
|
||||||
|
# # if there is no resource.
|
||||||
|
# # @return [Sitemap::Resource]
|
||||||
|
# def proxied_to_resource
|
||||||
|
# proxy_resource = store.find_resource_by_path(proxied_to)
|
||||||
|
|
||||||
|
# unless proxy_resource
|
||||||
|
# raise "Path #{path} proxies to unknown file #{proxied_to}:#{store.resources.map(&:path)}"
|
||||||
|
# end
|
||||||
|
|
||||||
|
# if proxy_resource.proxy?
|
||||||
|
# raise "You can't proxy #{path} to #{proxied_to} which is itself a proxy."
|
||||||
|
# end
|
||||||
|
|
||||||
|
# proxy_resource
|
||||||
|
# end
|
||||||
|
|
||||||
|
# def get_source_file
|
||||||
|
# if proxy?
|
||||||
|
# proxied_to_resource.source_file
|
||||||
|
# else
|
||||||
|
# super
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
# def content_type
|
||||||
|
# mime_type = super
|
||||||
|
# return mime_type if mime_type
|
||||||
|
|
||||||
|
# if proxy?
|
||||||
|
# proxied_to_resource.content_type
|
||||||
|
# else
|
||||||
|
# nil
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
module InstanceMethods
|
||||||
|
def endpoint_manager
|
||||||
|
@_endpoint_manager ||= EndpointManager.new(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def endpoint(*args, &block)
|
||||||
|
endpoint_manager.create_endpoint(*args, &block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Manages the list of proxy configurations and manipulates the sitemap
|
||||||
|
# to include new resources based on those configurations
|
||||||
|
class EndpointManager
|
||||||
|
def initialize(app)
|
||||||
|
@app = app
|
||||||
|
@endpoints = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Setup a proxy from a path to a target
|
||||||
|
# @param [String] path
|
||||||
|
# @param [Hash] The :path value gives a request path if it
|
||||||
|
# differs from the output path
|
||||||
|
# @return [void]
|
||||||
|
def create_endpoint(path, opts={}, &block)
|
||||||
|
endpoint = {
|
||||||
|
:request_path => path
|
||||||
|
}
|
||||||
|
|
||||||
|
if block_given?
|
||||||
|
endpoint[:output] = block
|
||||||
|
else
|
||||||
|
endpoint[:request_path] = opts[:path] if opts.has_key?(:path)
|
||||||
|
end
|
||||||
|
|
||||||
|
@endpoints[path] = endpoint
|
||||||
|
|
||||||
|
@app.sitemap.rebuild_resource_list!(:added_endpoint)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Update the main sitemap resource list
|
||||||
|
# @return [void]
|
||||||
|
def manipulate_resource_list(resources)
|
||||||
|
resources + @endpoints.map do |path, config|
|
||||||
|
r = EndpointResource.new(
|
||||||
|
@app.sitemap,
|
||||||
|
path,
|
||||||
|
config[:request_path]
|
||||||
|
)
|
||||||
|
r.output = config[:output] if config.has_key?(:output)
|
||||||
|
r
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class EndpointResource < ::Middleman::Sitemap::Resource
|
||||||
|
attr_accessor :output
|
||||||
|
|
||||||
|
def initialize(store, path, source_file)
|
||||||
|
@request_path = ::Middleman::Util.normalize_path(source_file)
|
||||||
|
|
||||||
|
super(store, path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def template?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(*args, &block)
|
||||||
|
return self.output.call if self.output
|
||||||
|
end
|
||||||
|
|
||||||
|
def request_path
|
||||||
|
@request_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def binary?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def raw_data
|
||||||
|
{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def ignored?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def metadata
|
||||||
|
@local_metadata.dup
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -105,6 +105,10 @@ module Middleman
|
||||||
File.extname(path)
|
File.extname(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def request_path
|
||||||
|
self.destination_path
|
||||||
|
end
|
||||||
|
|
||||||
# Render this resource
|
# Render this resource
|
||||||
# @return [String]
|
# @return [String]
|
||||||
def render(opts={}, locs={}, &block)
|
def render(opts={}, locs={}, &block)
|
||||||
|
|
|
@ -36,6 +36,9 @@ module Middleman
|
||||||
# Register classes which can manipulate the main site map list
|
# Register classes which can manipulate the main site map list
|
||||||
register_resource_list_manipulator(:on_disk, Middleman::Sitemap::Extensions::OnDisk.new(self))
|
register_resource_list_manipulator(:on_disk, Middleman::Sitemap::Extensions::OnDisk.new(self))
|
||||||
|
|
||||||
|
# Request Endpoints
|
||||||
|
register_resource_list_manipulator(:request_endpoints, @app.endpoint_manager)
|
||||||
|
|
||||||
# Proxies
|
# Proxies
|
||||||
register_resource_list_manipulator(:proxies, @app.proxy_manager)
|
register_resource_list_manipulator(:proxies, @app.proxy_manager)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue