Implement generic which is a simple way to build a file from Rack
This commit is contained in:
parent
f97c9ffab1
commit
913d2b7049
8 changed files with 251 additions and 2 deletions
|
@ -15,6 +15,7 @@
|
|||
===
|
||||
|
||||
* 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
|
||||
===
|
||||
|
|
|
@ -5,4 +5,63 @@ Feature: Support Rack apps mounted using map
|
|||
When I go to "/"
|
||||
Then I should see "Hello World (Middleman)"
|
||||
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
|
||||
"Hello World (Sinatra)"
|
||||
end
|
||||
get "/derp.html" do
|
||||
"De doo"
|
||||
end
|
||||
end
|
||||
|
||||
map "/sinatra" do
|
||||
|
|
|
@ -135,7 +135,7 @@ module Middleman::Cli
|
|||
FileUtils.cp(resource.source_file, output_file)
|
||||
else
|
||||
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
|
||||
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/extensions/on_disk"
|
||||
require "middleman-core/sitemap/extensions/request_endpoints"
|
||||
require "middleman-core/sitemap/extensions/proxies"
|
||||
require "middleman-core/sitemap/extensions/ignores"
|
||||
|
||||
|
@ -16,6 +17,7 @@ module Middleman
|
|||
# Once registered
|
||||
def registered(app)
|
||||
|
||||
app.register Middleman::Sitemap::Extensions::RequestEndpoints
|
||||
app.register Middleman::Sitemap::Extensions::Proxies
|
||||
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)
|
||||
end
|
||||
|
||||
def request_path
|
||||
self.destination_path
|
||||
end
|
||||
|
||||
# Render this resource
|
||||
# @return [String]
|
||||
def render(opts={}, locs={}, &block)
|
||||
|
|
|
@ -36,6 +36,9 @@ module Middleman
|
|||
# Register classes which can manipulate the main site map list
|
||||
register_resource_list_manipulator(:on_disk, Middleman::Sitemap::Extensions::OnDisk.new(self))
|
||||
|
||||
# Request Endpoints
|
||||
register_resource_list_manipulator(:request_endpoints, @app.endpoint_manager)
|
||||
|
||||
# Proxies
|
||||
register_resource_list_manipulator(:proxies, @app.proxy_manager)
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue