2012-05-07 23:41:39 +02:00
module Middleman
module Sitemap
module Extensions
2014-01-01 03:21:30 +01:00
# Manages the list of proxy configurations and manipulates the sitemap
# to include new resources based on those configurations
class Proxies
2014-05-28 08:05:37 +02:00
def initialize ( app )
@app = app
2014-01-01 03:21:30 +01:00
@app . add_to_config_context :proxy , & method ( :create_proxy )
@app . define_singleton_method ( :proxy , & method ( :create_proxy ) )
2012-08-14 00:39:06 +02:00
2014-01-01 03:21:30 +01:00
@proxy_configs = Set . new
2012-08-14 00:39:06 +02:00
2014-01-01 03:21:30 +01:00
:: Middleman :: Sitemap :: Resource . send :include , ProxyResourceInstanceMethods
2012-05-07 23:41:39 +02:00
end
2012-08-14 00:39:06 +02:00
2014-01-01 03:21:30 +01:00
# Setup a proxy from a path to a target
2014-06-17 06:44:14 +02:00
# @param [String] path The new, proxied path to create
# @param [String] target The existing path that should be proxied to. This must be a real resource, not another proxy.
# @option opts [Boolean] ignore Ignore the target from the sitemap (so only the new, proxy resource ends up in the output)
# @option opts [Symbol, Boolean, String] layout The layout name to use (e.g. `:article`) or `false` to disable layout.
# @option opts [Boolean] directory_indexes Whether or not the `:directory_indexes` extension applies to these paths.
# @option opts [Hash] locals Local variables for the template. These will be available when the template renders.
# @option opts [Hash] data Extra metadata to add to the page. This is the same as frontmatter, though frontmatter will take precedence over metadata defined here. Available via {Resource#data}.
2014-01-01 03:21:30 +01:00
# @return [void]
2014-01-04 00:49:54 +01:00
def create_proxy ( path , target , opts = { } )
options = opts . dup
2012-08-14 00:39:06 +02:00
2014-01-04 00:49:54 +01:00
@app . ignore ( target ) if options . delete ( :ignore )
2014-06-17 06:44:14 +02:00
metadata = {
options : options ,
locals : options . delete ( :locals ) || { } ,
page : options . delete ( :data ) || { }
}
2013-04-06 23:05:26 +02:00
2014-04-29 19:50:21 +02:00
@proxy_configs << ProxyConfiguration . new ( path : path , target : target , metadata : metadata )
2013-04-06 23:05:26 +02:00
2014-01-01 03:21:30 +01:00
@app . sitemap . rebuild_resource_list! ( :added_proxy )
end
2012-08-14 00:39:06 +02:00
2014-01-01 03:21:30 +01:00
# Update the main sitemap resource list
# @return [void]
def manipulate_resource_list ( resources )
resources + @proxy_configs . map do | config |
p = :: Middleman :: Sitemap :: Resource . new (
@app . sitemap ,
config . path
)
p . proxy_to ( config . target )
2014-01-04 00:49:54 +01:00
2014-01-01 03:21:30 +01:00
p . add_metadata ( config . metadata )
p
2013-04-06 23:05:26 +02:00
end
2014-01-01 03:21:30 +01:00
end
end
2012-08-14 00:39:06 +02:00
2014-01-01 03:21:30 +01:00
# Configuration for a proxy instance
class ProxyConfiguration
# The path that this proxy will appear at in the sitemap
attr_reader :path
def path = ( p )
@path = :: Middleman :: Util . normalize_path ( p )
end
2012-07-08 05:36:37 +02:00
2014-01-01 03:21:30 +01:00
# The existing sitemap path that this will proxy to
attr_reader :target
def target = ( t )
@target = :: Middleman :: Util . normalize_path ( t )
2012-04-04 19:26:07 +02:00
end
2012-08-14 00:39:06 +02:00
2014-01-04 00:49:54 +01:00
# Additional metadata like locals to apply to the proxy
2014-01-01 03:21:30 +01:00
attr_accessor :metadata
2012-08-14 00:39:06 +02:00
2014-01-01 03:21:30 +01:00
# Create a new proxy configuration from hash options
def initialize ( options = { } )
options . each do | key , value |
send " #{ key } = " , value
2012-05-07 23:41:39 +02:00
end
end
2012-08-14 00:39:06 +02:00
2014-01-01 03:21:30 +01:00
# Two configurations are equal if they reference the same path
def eql? ( other )
other . path == path
end
2012-10-12 06:19:15 +02:00
2014-01-01 03:21:30 +01:00
# Two configurations are equal if they reference the same path
def hash
path . hash
end
end
2012-10-12 06:19:15 +02:00
2014-01-01 03:21:30 +01:00
module ProxyResourceInstanceMethods
# Whether this page is a proxy
# @return [Boolean]
def proxy?
2014-04-29 20:43:05 +02:00
@proxied_to
2014-01-01 03:21:30 +01:00
end
2012-10-12 06:19:15 +02:00
2014-01-01 03:21:30 +01:00
# 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
2012-04-04 19:26:07 +02:00
2014-01-01 03:21:30 +01:00
# The path of the page this page is proxied to, or nil if it's not proxied.
# @return [String]
2014-04-29 19:50:21 +02:00
attr_reader :proxied_to
2012-10-12 06:19:15 +02:00
2014-01-01 03:21:30 +01:00
# 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
2014-05-28 08:05:37 +02:00
proxy_resource = @store . find_resource_by_path ( proxied_to )
2014-01-01 03:21:30 +01:00
unless proxy_resource
2014-05-28 08:05:37 +02:00
raise " Path #{ path } proxies to unknown file #{ proxied_to } : #{ @store . resources . map ( & :path ) } "
2012-10-12 06:19:15 +02:00
end
2014-01-01 03:21:30 +01:00
if proxy_resource . proxy?
raise " You can't proxy #{ path } to #{ proxied_to } which is itself a proxy. "
2012-10-12 06:19:15 +02:00
end
2014-01-01 03:21:30 +01:00
proxy_resource
end
2012-10-12 06:19:15 +02:00
2014-04-29 20:43:05 +02:00
# rubocop:disable AccessorMethodName
2014-01-01 03:21:30 +01:00
def get_source_file
if proxy?
proxied_to_resource . source_file
else
super
2012-10-12 06:19:15 +02:00
end
2014-01-01 03:21:30 +01:00
end
2012-10-12 06:19:15 +02:00
2014-01-01 03:21:30 +01:00
def content_type
mime_type = super
return mime_type if mime_type
2012-10-12 06:19:15 +02:00
2014-01-01 03:21:30 +01:00
if proxy?
proxied_to_resource . content_type
else
nil
2012-10-12 06:19:15 +02:00
end
end
2012-04-04 19:26:07 +02:00
end
end
end
2012-07-08 05:36:37 +02:00
end