finish moving rendering code into sitemap
This commit is contained in:
parent
9e1bf0c211
commit
51cb3980bc
8 changed files with 414 additions and 363 deletions
|
@ -73,12 +73,17 @@ module Middleman
|
||||||
autoload :Liquid, "middleman/renderers/liquid"
|
autoload :Liquid, "middleman/renderers/liquid"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module Sitemap
|
||||||
|
autoload :Store, "middleman/sitemap/store"
|
||||||
|
autoload :Page, "middleman/sitemap/page"
|
||||||
|
autoload :Template, "middleman/sitemap/template"
|
||||||
|
end
|
||||||
module CoreExtensions
|
module CoreExtensions
|
||||||
# File Change Notifier
|
# File Change Notifier
|
||||||
autoload :FileWatcher, "middleman/core_extensions/file_watcher"
|
autoload :FileWatcher, "middleman/core_extensions/file_watcher"
|
||||||
|
|
||||||
# In-memory Sitemap
|
# In-memory Sitemap
|
||||||
autoload :Sitemap, "middleman/core_extensions/sitemap"
|
autoload :Sitemap, "middleman/core_extensions/sitemap"
|
||||||
|
|
||||||
# Add Builder callbacks
|
# Add Builder callbacks
|
||||||
autoload :Builder, "middleman/core_extensions/builder"
|
autoload :Builder, "middleman/core_extensions/builder"
|
||||||
|
|
|
@ -193,92 +193,21 @@ class Middleman::Base
|
||||||
return not_found unless sitemap.exists?(@request_path)
|
return not_found unless sitemap.exists?(@request_path)
|
||||||
|
|
||||||
sitemap_page = sitemap.page(@request_path)
|
sitemap_page = sitemap.page(@request_path)
|
||||||
|
|
||||||
return not_found if sitemap_page.ignored?
|
return not_found if sitemap_page.ignored?
|
||||||
|
|
||||||
if sitemap.proxied?(@request_path)
|
|
||||||
@request_path = "/" + sitemap_page.proxied_to
|
|
||||||
sitemap_page = sitemap.page(sitemap_page.proxied_to)
|
|
||||||
end
|
|
||||||
|
|
||||||
found_template = resolve_template(@request_path)
|
|
||||||
return not_found unless found_template
|
|
||||||
|
|
||||||
@current_path = @request_path.dup
|
|
||||||
path, engine = found_template
|
|
||||||
|
|
||||||
# Static File
|
# Static File
|
||||||
return send_file(sitemap_page.source_file) unless sitemap_page.template?
|
return send_file(sitemap_page.source_file) unless sitemap_page.template?
|
||||||
|
|
||||||
|
@current_path = @request_path.dup
|
||||||
|
|
||||||
context = sitemap.page(full_path(@original_path.gsub("%20", " "))).template
|
content_type sitemap_page.mime_type
|
||||||
@options = context.options.dup
|
|
||||||
@locals = context.locals.dup
|
|
||||||
|
|
||||||
provides_metadata.each do |callback, matcher|
|
|
||||||
next if !matcher.nil? && !path.match(matcher)
|
|
||||||
instance_exec(path, &callback)
|
|
||||||
end
|
|
||||||
|
|
||||||
context.blocks.each do |block|
|
|
||||||
instance_eval(&block) if block
|
|
||||||
end
|
|
||||||
|
|
||||||
local_layout = if options.has_key?(:layout)
|
|
||||||
options[:layout]
|
|
||||||
elsif %w(.js .css .txt).include?(sitemap_page.ext)
|
|
||||||
false
|
|
||||||
else
|
|
||||||
layout
|
|
||||||
end
|
|
||||||
|
|
||||||
output = internal_render(path, locals, options)
|
|
||||||
|
|
||||||
if local_layout
|
|
||||||
engine_options = respond_to?(engine.to_sym) ? send(engine.to_sym) : {}
|
|
||||||
|
|
||||||
layout_engine = if options.has_key?(:layout_engine)
|
|
||||||
options[:layout_engine]
|
|
||||||
elsif engine_options.has_key?(:layout_engine)
|
|
||||||
engine_options[:layout_engine]
|
|
||||||
else
|
|
||||||
engine
|
|
||||||
end
|
|
||||||
|
|
||||||
layout_path, *etc = resolve_template(local_layout, :preferred_engine => layout_engine)
|
|
||||||
|
|
||||||
if !layout_path
|
|
||||||
local_layout = File.join("layouts", local_layout.to_s)
|
|
||||||
layout_path, *etc = resolve_template(local_layout, :preferred_engine => layout_engine)
|
|
||||||
end
|
|
||||||
|
|
||||||
throw "Could not locate layout: #{local_layout}" unless layout_path
|
|
||||||
|
|
||||||
output = internal_render(layout_path, locals, options) { output }
|
|
||||||
end
|
|
||||||
|
|
||||||
content_type mime_type(File.extname(@request_path))
|
|
||||||
res.status = 200
|
res.status = 200
|
||||||
res.write output
|
rqp = @request_path
|
||||||
|
res.write sitemap_page.render
|
||||||
halt res.finish
|
halt res.finish
|
||||||
end
|
end
|
||||||
|
|
||||||
public
|
public
|
||||||
def extensionless_path(file)
|
|
||||||
cache.fetch(:extensionless_path, file) do
|
|
||||||
path = file.dup
|
|
||||||
|
|
||||||
end_of_the_line = false
|
|
||||||
while !end_of_the_line
|
|
||||||
if !Tilt[path].nil?
|
|
||||||
path = path.sub(File.extname(path), "")
|
|
||||||
else
|
|
||||||
end_of_the_line = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def logging?
|
def logging?
|
||||||
logging
|
logging
|
||||||
|
|
|
@ -37,7 +37,6 @@ module Middleman::CoreExtensions::FrontMatter
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@options.merge!(data)
|
|
||||||
{ :options => data }
|
{ :options => data }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
require "active_support/core_ext/hash/deep_merge"
|
||||||
require 'find'
|
require 'find'
|
||||||
|
|
||||||
module Middleman::CoreExtensions::Sitemap
|
module Middleman::CoreExtensions::Sitemap
|
||||||
|
@ -22,7 +23,7 @@ module Middleman::CoreExtensions::Sitemap
|
||||||
end
|
end
|
||||||
|
|
||||||
def sitemap
|
def sitemap
|
||||||
@sitemap ||= SitemapStore.new(self)
|
@sitemap ||= ::Middleman::Sitemap::Store.new(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Keep a path from building
|
# Keep a path from building
|
||||||
|
@ -40,287 +41,4 @@ module Middleman::CoreExtensions::Sitemap
|
||||||
@_provides_metadata
|
@_provides_metadata
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class SitemapTemplate
|
|
||||||
attr_accessor :page, :options, :locals, :blocks#, :dependencies
|
|
||||||
|
|
||||||
def initialize(page)
|
|
||||||
@page = page
|
|
||||||
@options = {}
|
|
||||||
@locals = {}
|
|
||||||
@blocks = []
|
|
||||||
end
|
|
||||||
#
|
|
||||||
# def path
|
|
||||||
# @page.path
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# def store
|
|
||||||
# @page.store
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# def app
|
|
||||||
# store.app
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# def ext
|
|
||||||
# @page.ext
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# def metadata
|
|
||||||
# cache.fetch(:metadata, path) do
|
|
||||||
# metadata = {}
|
|
||||||
# provides_metadata.each do |callback, matcher|
|
|
||||||
# next if !matcher.nil? && !path.match(matcher)
|
|
||||||
# metadata.merge(instance_exec(path, &callback))
|
|
||||||
# end
|
|
||||||
# metadata
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# def render(opts={}, locs={})
|
|
||||||
# opts = options.merge(metadata[:options]).merge(opts)
|
|
||||||
# locs = locals.merge(metadata[:locals]).merge(locs)
|
|
||||||
#
|
|
||||||
# blocks.each do |block|
|
|
||||||
# instance_eval(&block)
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# content = app.internal_render(path, locals, options)
|
|
||||||
#
|
|
||||||
# if layout_path
|
|
||||||
# content = app.internal_render(layout_path, locals, options) { content }
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# content
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# protected
|
|
||||||
# def self.cache
|
|
||||||
# @_cache ||= ::Middleman::Cache.new
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# def cache
|
|
||||||
# self.class.cache
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# def options_for_ext(ext)
|
|
||||||
# cache.fetch(:options_for_ext, ext) do
|
|
||||||
# options = {}
|
|
||||||
#
|
|
||||||
# extension_class = Tilt[ext]
|
|
||||||
# Tilt.mappings.each do |ext, engines|
|
|
||||||
# next unless engines.include? extension_class
|
|
||||||
# engine_options = respond_to?(ext.to_sym) ? send(ext.to_sym) : {}
|
|
||||||
# options.merge!(engine_options)
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# options
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# def layout_path
|
|
||||||
# return false if %w(.js .css .txt).include?(ext)
|
|
||||||
# local_layout = options.has_key?(:layout) ? options[:layout] : app.layout
|
|
||||||
# return false unless local_layout
|
|
||||||
#
|
|
||||||
# engine_options = app.respond_to?(engine.to_sym) ? app.send(engine.to_sym) : {}
|
|
||||||
#
|
|
||||||
# layout_engine = if options.has_key?(:layout_engine)
|
|
||||||
# options[:layout_engine]
|
|
||||||
# elsif engine_options.has_key?(:layout_engine)
|
|
||||||
# engine_options[:layout_engine]
|
|
||||||
# else
|
|
||||||
# engine
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# layout_path, *etc = app.resolve_template(local_layout, :preferred_engine => layout_engine)
|
|
||||||
#
|
|
||||||
# if !layout_path
|
|
||||||
# local_layout = File.join("layouts", local_layout.to_s)
|
|
||||||
# layout_path, *etc = app.resolve_template(local_layout, :preferred_engine => layout_engine)
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# throw "Could not locate layout: #{local_layout}" unless layout_path
|
|
||||||
# layout_path
|
|
||||||
end
|
|
||||||
|
|
||||||
class SitemapPage
|
|
||||||
attr_accessor :path, :source_file, :proxied_to, :status
|
|
||||||
|
|
||||||
def initialize(store, path)
|
|
||||||
@store = store
|
|
||||||
@path = path
|
|
||||||
@status = :generic
|
|
||||||
@source_file = nil
|
|
||||||
@proxied_to = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def template?
|
|
||||||
return false if source_file.nil?
|
|
||||||
!Tilt[source_file].nil?
|
|
||||||
end
|
|
||||||
|
|
||||||
def template
|
|
||||||
@_template ||= SitemapTemplate.new(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
def ext
|
|
||||||
File.extname(path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def mime_type
|
|
||||||
@store.app.mime_type ext
|
|
||||||
end
|
|
||||||
|
|
||||||
def proxy?
|
|
||||||
@status == :proxy
|
|
||||||
end
|
|
||||||
|
|
||||||
def proxy_to(target)
|
|
||||||
@status = :proxy
|
|
||||||
@proxied_to = target
|
|
||||||
end
|
|
||||||
|
|
||||||
def generic?
|
|
||||||
@status == :generic
|
|
||||||
end
|
|
||||||
|
|
||||||
def make_generic
|
|
||||||
@status = :generic
|
|
||||||
end
|
|
||||||
|
|
||||||
def ignored?
|
|
||||||
@status == :ignored
|
|
||||||
end
|
|
||||||
|
|
||||||
def ignore
|
|
||||||
@status = :ignored
|
|
||||||
end
|
|
||||||
|
|
||||||
def touch
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
def app
|
|
||||||
@store.app
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class SitemapStore
|
|
||||||
attr_accessor :app
|
|
||||||
|
|
||||||
def initialize(app)
|
|
||||||
@app = app
|
|
||||||
@cache = ::Middleman::Cache.new
|
|
||||||
@source = File.expand_path(@app.views, @app.root)
|
|
||||||
@pages = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
# Check to see if we know about a specific path
|
|
||||||
def exists?(path)
|
|
||||||
@pages.has_key?(path.sub(/^\//, ""))
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_context(path, opts={}, blk=nil)
|
|
||||||
page(path) do
|
|
||||||
template.options = opts
|
|
||||||
template.blocks = [blk]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def ignore(path)
|
|
||||||
page(path) { ignore }
|
|
||||||
@cache.remove(:ignored_paths)
|
|
||||||
end
|
|
||||||
|
|
||||||
def proxy(path, target)
|
|
||||||
page(path) { proxy_to(target.sub(%r{^/}, "")) }
|
|
||||||
@cache.remove(:proxied_paths)
|
|
||||||
end
|
|
||||||
|
|
||||||
def page(path, &block)
|
|
||||||
path = path.sub(/^\//, "").gsub("%20", " ")
|
|
||||||
@pages[path] = SitemapPage.new(self, path) unless @pages.has_key?(path)
|
|
||||||
@pages[path].instance_exec(&block) if block_given?
|
|
||||||
@pages[path]
|
|
||||||
end
|
|
||||||
|
|
||||||
def all_paths
|
|
||||||
@pages.keys
|
|
||||||
end
|
|
||||||
|
|
||||||
def ignored?(path)
|
|
||||||
ignored_paths.include?(path.sub(/^\//, ""))
|
|
||||||
end
|
|
||||||
|
|
||||||
def ignored_paths
|
|
||||||
@cache.fetch :ignored_paths do
|
|
||||||
@pages.values.select(&:ignored?).map(&:path)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def generic?(path)
|
|
||||||
generic_paths.include?(path.sub(/^\//, ""))
|
|
||||||
end
|
|
||||||
|
|
||||||
def generic_paths
|
|
||||||
@cache.fetch :generic_paths do
|
|
||||||
@pages.values.select(&:generic?).map(&:path)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def proxied?(path)
|
|
||||||
proxied_paths.include?(path.sub(/^\//, ""))
|
|
||||||
end
|
|
||||||
|
|
||||||
def proxied_paths
|
|
||||||
@cache.fetch :proxied_paths do
|
|
||||||
@pages.values.select(&:proxy?).map(&:path)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove_file(file)
|
|
||||||
path = file_to_path(file)
|
|
||||||
return false unless path
|
|
||||||
|
|
||||||
path = path.sub(/^\//, "")
|
|
||||||
@pages.delete(path) if @pages.has_key?(path)
|
|
||||||
@context_map.delete(path) if @context_map.has_key?(path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def file_to_path(file)
|
|
||||||
file = File.expand_path(file, @app.root)
|
|
||||||
|
|
||||||
prefix = @source + "/"
|
|
||||||
return false unless file.include?(prefix)
|
|
||||||
|
|
||||||
path = file.sub(prefix, "")
|
|
||||||
path = @app.extensionless_path(path)
|
|
||||||
|
|
||||||
path
|
|
||||||
end
|
|
||||||
|
|
||||||
def touch_file(file)
|
|
||||||
return false if file == @source ||
|
|
||||||
file.match(/^\./) ||
|
|
||||||
file.match(/\/\./) ||
|
|
||||||
(file.match(/\/_/) && !file.match(/\/__/)) ||
|
|
||||||
File.directory?(file)
|
|
||||||
|
|
||||||
path = file_to_path(file)
|
|
||||||
|
|
||||||
return false unless path
|
|
||||||
|
|
||||||
return false if path.match(%r{^layout}) ||
|
|
||||||
path.match(%r{^layouts/})
|
|
||||||
|
|
||||||
# @app.logger.debug :sitemap_update, Time.now, path if @app.logging?
|
|
||||||
|
|
||||||
# Add generic path
|
|
||||||
page(path).source_file = File.expand_path(file, @app.root)
|
|
||||||
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
|
@ -10,7 +10,6 @@ module Middleman::Renderers::Liquid
|
||||||
Liquid::Template.file_system = Liquid::LocalFileSystem.new(self.source_dir)
|
Liquid::Template.file_system = Liquid::LocalFileSystem.new(self.source_dir)
|
||||||
|
|
||||||
provides_metadata %r{\.liquid$} do |path|
|
provides_metadata %r{\.liquid$} do |path|
|
||||||
@locals.merge!(:data => data.to_h)
|
|
||||||
{ :locals => { :data => data.to_h } }
|
{ :locals => { :data => data.to_h } }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
96
lib/middleman/sitemap/page.rb
Normal file
96
lib/middleman/sitemap/page.rb
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
module Middleman::Sitemap
|
||||||
|
class Page
|
||||||
|
attr_accessor :store, :path, :proxied_to, :status
|
||||||
|
|
||||||
|
def initialize(store, path)
|
||||||
|
@store = store
|
||||||
|
@path = path
|
||||||
|
@status = :generic
|
||||||
|
@source_file = nil
|
||||||
|
@proxied_to = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def template?
|
||||||
|
if proxy?
|
||||||
|
store.page(proxied_to).template?
|
||||||
|
else
|
||||||
|
return false if source_file.nil?
|
||||||
|
!::Tilt[source_file].nil?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def source_file=(src)
|
||||||
|
@source_file = src
|
||||||
|
end
|
||||||
|
|
||||||
|
def source_file
|
||||||
|
if proxy?
|
||||||
|
store.page(proxied_to).source_file
|
||||||
|
else
|
||||||
|
@source_file
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def template
|
||||||
|
@_template ||= ::Middleman::Sitemap::Template.new(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ext
|
||||||
|
File.extname(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def mime_type
|
||||||
|
app.mime_type ext
|
||||||
|
end
|
||||||
|
|
||||||
|
def proxy?
|
||||||
|
@status == :proxy
|
||||||
|
end
|
||||||
|
|
||||||
|
def proxy_to(target)
|
||||||
|
@status = :proxy
|
||||||
|
@proxied_to = target
|
||||||
|
end
|
||||||
|
|
||||||
|
def generic?
|
||||||
|
@status == :generic
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_generic
|
||||||
|
@status = :generic
|
||||||
|
end
|
||||||
|
|
||||||
|
def ignored?
|
||||||
|
@status == :ignored
|
||||||
|
end
|
||||||
|
|
||||||
|
def ignore
|
||||||
|
@status = :ignored
|
||||||
|
end
|
||||||
|
|
||||||
|
def touch
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(&block)
|
||||||
|
return unless template?
|
||||||
|
|
||||||
|
if proxy?
|
||||||
|
# Forward blocks
|
||||||
|
forward_blocks = template.blocks.compact
|
||||||
|
forward_blocks << block if block_given?
|
||||||
|
store.page(proxied_to).template.render do
|
||||||
|
forward_blocks.each do |block|
|
||||||
|
instance_exec(&block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
template.render(&block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
def app
|
||||||
|
@store.app
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
137
lib/middleman/sitemap/store.rb
Normal file
137
lib/middleman/sitemap/store.rb
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
module Middleman::Sitemap
|
||||||
|
class Store
|
||||||
|
attr_accessor :app
|
||||||
|
|
||||||
|
def initialize(app)
|
||||||
|
@app = app
|
||||||
|
@cache = ::Middleman::Cache.new
|
||||||
|
@source = File.expand_path(@app.views, @app.root)
|
||||||
|
@pages = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check to see if we know about a specific path
|
||||||
|
def exists?(path)
|
||||||
|
@pages.has_key?(path.sub(/^\//, ""))
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_context(path, opts={}, blk=nil)
|
||||||
|
page(path) do
|
||||||
|
template.options = opts
|
||||||
|
template.blocks = [blk]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def ignore(path)
|
||||||
|
page(path) { ignore }
|
||||||
|
@cache.remove(:ignored_paths)
|
||||||
|
end
|
||||||
|
|
||||||
|
def proxy(path, target)
|
||||||
|
page(path) { proxy_to(target.sub(%r{^/}, "")) }
|
||||||
|
@cache.remove(:proxied_paths)
|
||||||
|
end
|
||||||
|
|
||||||
|
def page(path, &block)
|
||||||
|
path = path.sub(/^\//, "").gsub("%20", " ")
|
||||||
|
@pages[path] = ::Middleman::Sitemap::Page.new(self, path) unless @pages.has_key?(path)
|
||||||
|
@pages[path].instance_exec(&block) if block_given?
|
||||||
|
@pages[path]
|
||||||
|
end
|
||||||
|
|
||||||
|
def all_paths
|
||||||
|
@pages.keys
|
||||||
|
end
|
||||||
|
|
||||||
|
def ignored?(path)
|
||||||
|
ignored_paths.include?(path.sub(/^\//, ""))
|
||||||
|
end
|
||||||
|
|
||||||
|
def ignored_paths
|
||||||
|
@cache.fetch :ignored_paths do
|
||||||
|
@pages.values.select(&:ignored?).map(&:path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def generic?(path)
|
||||||
|
generic_paths.include?(path.sub(/^\//, ""))
|
||||||
|
end
|
||||||
|
|
||||||
|
def generic_paths
|
||||||
|
@cache.fetch :generic_paths do
|
||||||
|
@pages.values.select(&:generic?).map(&:path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def proxied?(path)
|
||||||
|
proxied_paths.include?(path.sub(/^\//, ""))
|
||||||
|
end
|
||||||
|
|
||||||
|
def proxied_paths
|
||||||
|
@cache.fetch :proxied_paths do
|
||||||
|
@pages.values.select(&:proxy?).map(&:path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_file(file)
|
||||||
|
path = file_to_path(file)
|
||||||
|
return false unless path
|
||||||
|
|
||||||
|
path = path.sub(/^\//, "")
|
||||||
|
@pages.delete(path) if @pages.has_key?(path)
|
||||||
|
@context_map.delete(path) if @context_map.has_key?(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_to_path(file)
|
||||||
|
file = File.expand_path(file, @app.root)
|
||||||
|
|
||||||
|
prefix = @source + "/"
|
||||||
|
return false unless file.include?(prefix)
|
||||||
|
|
||||||
|
path = file.sub(prefix, "")
|
||||||
|
path = extensionless_path(path)
|
||||||
|
|
||||||
|
path
|
||||||
|
end
|
||||||
|
|
||||||
|
def touch_file(file)
|
||||||
|
return false if file == @source ||
|
||||||
|
file.match(/^\./) ||
|
||||||
|
file.match(/\/\./) ||
|
||||||
|
(file.match(/\/_/) && !file.match(/\/__/)) ||
|
||||||
|
File.directory?(file)
|
||||||
|
|
||||||
|
path = file_to_path(file)
|
||||||
|
|
||||||
|
return false unless path
|
||||||
|
|
||||||
|
return false if path.match(%r{^layout}) ||
|
||||||
|
path.match(%r{^layouts/})
|
||||||
|
|
||||||
|
# @app.logger.debug :sitemap_update, Time.now, path if @app.logging?
|
||||||
|
|
||||||
|
# Add generic path
|
||||||
|
page(path).source_file = File.expand_path(file, @app.root)
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
def extensionless_path(file)
|
||||||
|
@cache ||= ::Middleman::Cache.new
|
||||||
|
@cache.fetch(:extensionless_path, file) do
|
||||||
|
path = file.dup
|
||||||
|
|
||||||
|
end_of_the_line = false
|
||||||
|
while !end_of_the_line
|
||||||
|
if !::Tilt[path].nil?
|
||||||
|
path = path.sub(File.extname(path), "")
|
||||||
|
else
|
||||||
|
end_of_the_line = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
168
lib/middleman/sitemap/template.rb
Normal file
168
lib/middleman/sitemap/template.rb
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
module Middleman::Sitemap
|
||||||
|
class Template
|
||||||
|
attr_accessor :page, :options, :locals, :blocks#, :dependencies
|
||||||
|
|
||||||
|
def initialize(page)
|
||||||
|
@page = page
|
||||||
|
@options = {}
|
||||||
|
@locals = {}
|
||||||
|
@blocks = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def path
|
||||||
|
page.path
|
||||||
|
end
|
||||||
|
|
||||||
|
def source_file
|
||||||
|
page.source_file
|
||||||
|
end
|
||||||
|
|
||||||
|
def store
|
||||||
|
page.store
|
||||||
|
end
|
||||||
|
|
||||||
|
def app
|
||||||
|
store.app
|
||||||
|
end
|
||||||
|
|
||||||
|
def ext
|
||||||
|
page.ext
|
||||||
|
end
|
||||||
|
|
||||||
|
def metadata
|
||||||
|
cache.fetch(:metadata, source_file) do
|
||||||
|
metadata = { :options => {}, :locals => {} }
|
||||||
|
app.provides_metadata.each do |callback, matcher|
|
||||||
|
next if !matcher.nil? && !source_file.match(matcher)
|
||||||
|
result = app.instance_exec(source_file, &callback)
|
||||||
|
metadata = metadata.deep_merge(result)
|
||||||
|
end
|
||||||
|
metadata
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(opts={}, locs={}, &block)
|
||||||
|
opts = options.deep_merge(metadata[:options]).deep_merge(opts)
|
||||||
|
locs = locals.deep_merge(metadata[:locals]).deep_merge(locs)
|
||||||
|
|
||||||
|
blocks.compact.each do |block|
|
||||||
|
app.instance_eval(&block)
|
||||||
|
end
|
||||||
|
|
||||||
|
app.instance_eval(&block) if block_given?
|
||||||
|
|
||||||
|
content = internal_render(source_file, locs, opts)
|
||||||
|
|
||||||
|
if layout_path = fetch_layout(opts)
|
||||||
|
content = internal_render(layout_path, locs, opts) { content }
|
||||||
|
end
|
||||||
|
|
||||||
|
content
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
def self.cache
|
||||||
|
@_cache ||= ::Middleman::Cache.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def cache
|
||||||
|
self.class.cache
|
||||||
|
end
|
||||||
|
|
||||||
|
def options_for_ext(ext)
|
||||||
|
cache.fetch(:options_for_ext, ext) do
|
||||||
|
options = {}
|
||||||
|
|
||||||
|
extension_class = ::Tilt[ext]
|
||||||
|
::Tilt.mappings.each do |ext, engines|
|
||||||
|
next unless engines.include? extension_class
|
||||||
|
engine_options = respond_to?(ext.to_sym) ? send(ext.to_sym) : {}
|
||||||
|
options.merge!(engine_options)
|
||||||
|
end
|
||||||
|
|
||||||
|
options
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_layout(opts)
|
||||||
|
return false if %w(.js .css .txt).include?(ext)
|
||||||
|
local_layout = opts.has_key?(:layout) ? opts[:layout] : app.layout
|
||||||
|
return false unless local_layout
|
||||||
|
|
||||||
|
engine = File.extname(source_file)[1..-1].to_sym
|
||||||
|
engine_options = app.respond_to?(engine) ? app.send(engine) : {}
|
||||||
|
|
||||||
|
layout_engine = if opts.has_key?(:layout_engine)
|
||||||
|
opts[:layout_engine]
|
||||||
|
elsif engine_options.has_key?(:layout_engine)
|
||||||
|
engine_options[:layout_engine]
|
||||||
|
else
|
||||||
|
engine
|
||||||
|
end
|
||||||
|
|
||||||
|
layout_path, *etc = resolve_template(local_layout, :preferred_engine => layout_engine)
|
||||||
|
|
||||||
|
if !layout_path
|
||||||
|
local_layout = File.join("layouts", local_layout.to_s)
|
||||||
|
layout_path, *etc = resolve_template(local_layout, :preferred_engine => layout_engine)
|
||||||
|
end
|
||||||
|
|
||||||
|
throw "Could not locate layout: #{local_layout}" unless layout_path
|
||||||
|
layout_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def resolve_template(request_path, options={})
|
||||||
|
request_path = request_path.to_s
|
||||||
|
cache.fetch(:resolve_template, request_path, options) do
|
||||||
|
relative_path = request_path.sub(%r{^/}, "")
|
||||||
|
on_disk_path = File.expand_path(relative_path, app.source_dir)
|
||||||
|
|
||||||
|
preferred_engine = if options.has_key?(:preferred_engine)
|
||||||
|
extension_class = ::Tilt[options[:preferred_engine]]
|
||||||
|
matched_exts = []
|
||||||
|
|
||||||
|
# TODO: Cache this
|
||||||
|
::Tilt.mappings.each do |ext, engines|
|
||||||
|
next unless engines.include? extension_class
|
||||||
|
matched_exts << ext
|
||||||
|
end
|
||||||
|
|
||||||
|
"{" + matched_exts.join(",") + "}"
|
||||||
|
else
|
||||||
|
"*"
|
||||||
|
end
|
||||||
|
|
||||||
|
path_with_ext = on_disk_path + "." + preferred_engine
|
||||||
|
|
||||||
|
found_path = Dir[path_with_ext].find do |path|
|
||||||
|
::Tilt[path]
|
||||||
|
end
|
||||||
|
|
||||||
|
result = if found_path || File.exists?(on_disk_path)
|
||||||
|
engine = found_path ? File.extname(found_path)[1..-1].to_sym : nil
|
||||||
|
[ found_path || on_disk_path, engine ]
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def internal_render(path, locs = {}, opts = {}, &block)
|
||||||
|
path = path.to_s
|
||||||
|
|
||||||
|
opts.merge!(options_for_ext(File.extname(path)))
|
||||||
|
|
||||||
|
body = app.cache.fetch(:raw_template, path) do
|
||||||
|
File.read(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
template = cache.fetch(:compiled_template, options, body) do
|
||||||
|
::Tilt.new(path, 1, options) { body }
|
||||||
|
end
|
||||||
|
|
||||||
|
template.render(app, locs, &block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue