move rendering into rendering extension, instead of sitemap
This commit is contained in:
parent
7c50c9e4d5
commit
fed3dd5a85
|
@ -176,15 +176,15 @@ class Middleman::Base
|
||||||
# Add Guard Callbacks
|
# Add Guard Callbacks
|
||||||
register Middleman::CoreExtensions::FileWatcher
|
register Middleman::CoreExtensions::FileWatcher
|
||||||
|
|
||||||
# Sitemap
|
|
||||||
register Middleman::CoreExtensions::Sitemap
|
|
||||||
|
|
||||||
# Activate Data package
|
# Activate Data package
|
||||||
register Middleman::CoreExtensions::Data
|
register Middleman::CoreExtensions::Data
|
||||||
|
|
||||||
# Setup custom rendering
|
# Setup custom rendering
|
||||||
register Middleman::CoreExtensions::Rendering
|
register Middleman::CoreExtensions::Rendering
|
||||||
|
|
||||||
|
# Sitemap
|
||||||
|
register Middleman::CoreExtensions::Sitemap
|
||||||
|
|
||||||
# Compass framework
|
# Compass framework
|
||||||
register Middleman::CoreExtensions::Compass
|
register Middleman::CoreExtensions::Compass
|
||||||
|
|
||||||
|
@ -231,6 +231,8 @@ class Middleman::Base
|
||||||
# Current path defaults to nil, used in views.
|
# Current path defaults to nil, used in views.
|
||||||
@current_path = nil
|
@current_path = nil
|
||||||
|
|
||||||
|
cache.clear
|
||||||
|
|
||||||
# Setup the default values from calls to set before initialization
|
# Setup the default values from calls to set before initialization
|
||||||
self.class.superclass.defaults.each { |k,v| set k,v }
|
self.class.superclass.defaults.each { |k,v| set k,v }
|
||||||
|
|
||||||
|
@ -250,10 +252,18 @@ class Middleman::Base
|
||||||
#
|
#
|
||||||
# @private
|
# @private
|
||||||
# @return [Middleman::Cache] The cache
|
# @return [Middleman::Cache] The cache
|
||||||
def cache
|
def self.cache
|
||||||
@_cache ||= ::Middleman::Cache.new
|
@_cache ||= ::Middleman::Cache.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Cache accessor for instance, simply forwards to class
|
||||||
|
#
|
||||||
|
# @private
|
||||||
|
# @return [Middleman::Cache] The cache
|
||||||
|
def cache
|
||||||
|
self.class.cache
|
||||||
|
end
|
||||||
|
|
||||||
# Rack env
|
# Rack env
|
||||||
attr :env
|
attr :env
|
||||||
|
|
||||||
|
@ -334,7 +344,7 @@ class Middleman::Base
|
||||||
|
|
||||||
# Valid content is a 200 status
|
# Valid content is a 200 status
|
||||||
res.status = 200
|
res.status = 200
|
||||||
rescue ::Middleman::Sitemap::TemplateNotFound => e
|
rescue Middleman::CoreExtensions::Rendering::TemplateNotFound => e
|
||||||
res.write "Error: #{e.message}"
|
res.write "Error: #{e.message}"
|
||||||
res.status = 500
|
res.status = 500
|
||||||
end
|
end
|
||||||
|
@ -372,54 +382,6 @@ class Middleman::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sinatra/Padrino render method signature. Simply forwards to the sitemap
|
|
||||||
#
|
|
||||||
# @param [Symbol] Engine name
|
|
||||||
# @param [String] Path
|
|
||||||
# @param [Hash] Rendering options
|
|
||||||
# @param [Hash] Rendering locals
|
|
||||||
# @return [String] Output
|
|
||||||
def render(engine, data, options={}, locals={}, &block)
|
|
||||||
data = data.to_s
|
|
||||||
|
|
||||||
found_partial = false
|
|
||||||
engine = nil
|
|
||||||
|
|
||||||
if sitemap.exists?(current_path)
|
|
||||||
page = sitemap.page(current_path)
|
|
||||||
current_dir = File.dirname(page.source_file)
|
|
||||||
engine = File.extname(page.source_file)[1..-1].to_sym
|
|
||||||
|
|
||||||
if current_dir != self.source_dir
|
|
||||||
relative_dir = File.join(current_dir.sub("#{self.source_dir}/", ""), data)
|
|
||||||
|
|
||||||
found_partial, found_engine = Middleman::Sitemap::Template.resolve_template(self, relative_dir, :preferred_engine => engine)
|
|
||||||
|
|
||||||
if !found_partial
|
|
||||||
found_partial, found_engine = Middleman::Sitemap::Template.resolve_template(self, relative_dir)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if !found_partial && !engine.nil?
|
|
||||||
found_partial, found_engine = Middleman::Sitemap::Template.resolve_template(self, data, :preferred_engine => engine)
|
|
||||||
end
|
|
||||||
|
|
||||||
if !found_partial
|
|
||||||
found_partial, found_engine = Middleman::Sitemap::Template.resolve_template(self, data)
|
|
||||||
end
|
|
||||||
|
|
||||||
if found_partial
|
|
||||||
body = cache.fetch(:raw_template, found_partial) do
|
|
||||||
File.read(found_partial)
|
|
||||||
end
|
|
||||||
|
|
||||||
Middleman::Sitemap::Template.static_render(self, found_partial, body, locals, options, &block)
|
|
||||||
else
|
|
||||||
throw "Could not find file to render: #{data}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Add a new mime-type for a specific extension
|
# Add a new mime-type for a specific extension
|
||||||
#
|
#
|
||||||
# @param [Symbol] File extension
|
# @param [Symbol] File extension
|
||||||
|
|
|
@ -9,6 +9,8 @@ module Middleman::CoreExtensions::Rendering
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
end
|
end
|
||||||
|
|
||||||
|
app.send :include, InstanceMethods
|
||||||
|
|
||||||
# Activate custom renderers
|
# Activate custom renderers
|
||||||
app.register Middleman::Renderers::Sass
|
app.register Middleman::Renderers::Sass
|
||||||
app.register Middleman::Renderers::Markdown
|
app.register Middleman::Renderers::Markdown
|
||||||
|
@ -17,4 +19,191 @@ module Middleman::CoreExtensions::Rendering
|
||||||
end
|
end
|
||||||
alias :included :registered
|
alias :included :registered
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class TemplateNotFound < RuntimeError
|
||||||
|
end
|
||||||
|
|
||||||
|
module InstanceMethods
|
||||||
|
def render_template(path, locs={}, opts={})
|
||||||
|
content = render_individual_file(path, locs, opts)
|
||||||
|
|
||||||
|
extension = File.extname(path)
|
||||||
|
needs_layout = !%w(.js .css .txt).include?(extension)
|
||||||
|
engine = extension[1..-1].to_sym
|
||||||
|
|
||||||
|
if needs_layout && layout_path = fetch_layout(engine, opts)
|
||||||
|
content = render_individual_file(layout_path, locs, opts) { content }
|
||||||
|
end
|
||||||
|
|
||||||
|
content
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sinatra/Padrino render method signature.
|
||||||
|
def render(engine, data, options={}, locals={}, &block)
|
||||||
|
data = data.to_s
|
||||||
|
|
||||||
|
found_partial = false
|
||||||
|
engine = nil
|
||||||
|
|
||||||
|
if sitemap.exists?(current_path)
|
||||||
|
page = sitemap.page(current_path)
|
||||||
|
current_dir = File.dirname(page.source_file)
|
||||||
|
engine = File.extname(page.source_file)[1..-1].to_sym
|
||||||
|
|
||||||
|
if current_dir != self.source_dir
|
||||||
|
relative_dir = File.join(current_dir.sub("#{self.source_dir}/", ""), data)
|
||||||
|
|
||||||
|
found_partial, found_engine = resolve_template(relative_dir, :preferred_engine => engine)
|
||||||
|
|
||||||
|
if !found_partial
|
||||||
|
found_partial, found_engine = resolve_template(relative_dir)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if !found_partial && !engine.nil?
|
||||||
|
found_partial, found_engine = resolve_template(data, :preferred_engine => engine)
|
||||||
|
end
|
||||||
|
|
||||||
|
if !found_partial
|
||||||
|
found_partial, found_engine = resolve_template(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
if found_partial
|
||||||
|
render_individual_file(found_partial, locals, options, &block)
|
||||||
|
else
|
||||||
|
raise ::Middleman::CoreExtensions::Rendering::TemplateNotFound, "Could not locate partial: #{data}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# @private
|
||||||
|
def render_individual_file(path, locs = {}, opts = {}, &block)
|
||||||
|
path = path.to_s
|
||||||
|
body = cache.fetch(:raw_template, path) do
|
||||||
|
File.read(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
options = opts.merge(options_for_ext(File.extname(path)))
|
||||||
|
|
||||||
|
template = cache.fetch(:compiled_template, options, body) do
|
||||||
|
::Tilt.new(path, 1, options) { body }
|
||||||
|
end
|
||||||
|
|
||||||
|
template.render(self, locs, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
# @private
|
||||||
|
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
|
||||||
|
|
||||||
|
# @private
|
||||||
|
def fetch_layout(engine, opts)
|
||||||
|
local_layout = opts.has_key?(:layout) ? opts[:layout] : layout
|
||||||
|
return false unless local_layout
|
||||||
|
|
||||||
|
engine_options = respond_to?(engine) ? 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
|
||||||
|
|
||||||
|
# Automatic
|
||||||
|
if local_layout == :_auto_layout
|
||||||
|
# Look for :layout of any extension
|
||||||
|
# If found, use it. If not, continue
|
||||||
|
locate_layout(:layout, layout_engine) || false
|
||||||
|
else
|
||||||
|
# Look for specific layout
|
||||||
|
# If found, use it. If not, error.
|
||||||
|
if layout_path = locate_layout(local_layout, layout_engine)
|
||||||
|
layout_path
|
||||||
|
else
|
||||||
|
raise ::Middleman::CoreExtensions::Rendering::TemplateNotFound, "Could not locate layout: #{local_layout}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# @private
|
||||||
|
def locate_layout(name, preferred_engine=nil)
|
||||||
|
layout_path = false
|
||||||
|
|
||||||
|
if !preferred_engine.nil?
|
||||||
|
# Check root
|
||||||
|
layout_path, layout_engine = resolve_template(name, :preferred_engine => preferred_engine)
|
||||||
|
|
||||||
|
# Check layouts folder
|
||||||
|
if !layout_path
|
||||||
|
layout_path, layout_engine = resolve_template(File.join("layouts", name.to_s), :preferred_engine => preferred_engine)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check root, no preference
|
||||||
|
if !layout_path
|
||||||
|
layout_path, layout_engine = resolve_template(name)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check layouts folder, no preference
|
||||||
|
if !layout_path
|
||||||
|
layout_path, layout_engine = resolve_template(File.join("layouts", name.to_s))
|
||||||
|
end
|
||||||
|
|
||||||
|
layout_path
|
||||||
|
end
|
||||||
|
|
||||||
|
# @private
|
||||||
|
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, self.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
|
||||||
|
|
||||||
|
if matched_exts.length > 0
|
||||||
|
preferred_engine = "{" + matched_exts.join(",") + "}"
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
path_with_ext = on_disk_path + "." + preferred_engine
|
||||||
|
found_path = Dir[path_with_ext].find do |path|
|
||||||
|
::Tilt[path]
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
|
@ -1,6 +1,4 @@
|
||||||
module Middleman::Sitemap
|
module Middleman::Sitemap
|
||||||
class TemplateNotFound < RuntimeError
|
|
||||||
end
|
|
||||||
|
|
||||||
class Template
|
class Template
|
||||||
attr_accessor :page, :options, :locals, :blocks#, :dependencies
|
attr_accessor :page, :options, :locals, :blocks#, :dependencies
|
||||||
|
@ -53,14 +51,7 @@ module Middleman::Sitemap
|
||||||
end
|
end
|
||||||
|
|
||||||
app.instance_eval(&block) if block_given?
|
app.instance_eval(&block) if block_given?
|
||||||
|
app.render_template(source_file, locs, opts)
|
||||||
content = internal_render(source_file, locs, opts)
|
|
||||||
|
|
||||||
if layout_path = fetch_layout(opts)
|
|
||||||
content = internal_render(layout_path, locs, opts) { content }
|
|
||||||
end
|
|
||||||
|
|
||||||
content
|
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
@ -71,136 +62,5 @@ module Middleman::Sitemap
|
||||||
def cache
|
def cache
|
||||||
self.class.cache
|
self.class.cache
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.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
|
|
||||||
|
|
||||||
# Automatic
|
|
||||||
if local_layout == :_auto_layout
|
|
||||||
# Look for :layout of any extension
|
|
||||||
# If found, use it. If not, continue
|
|
||||||
locate_layout(:layout, layout_engine) || false
|
|
||||||
else
|
|
||||||
# Look for specific layout
|
|
||||||
# If found, use it. If not, error.
|
|
||||||
if layout_path = locate_layout(local_layout, layout_engine)
|
|
||||||
layout_path
|
|
||||||
else
|
|
||||||
raise Middleman::Sitemap::TemplateNotFound, "Could not locate layout: #{local_layout}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def locate_layout(name, preferred_engine=nil)
|
|
||||||
layout_path = false
|
|
||||||
|
|
||||||
if !preferred_engine.nil?
|
|
||||||
# Check root
|
|
||||||
layout_path, *etc = self.class.resolve_template(app, name, :preferred_engine => preferred_engine)
|
|
||||||
|
|
||||||
# Check layouts folder
|
|
||||||
if !layout_path
|
|
||||||
layout_path, *etc = self.class.resolve_template(app, File.join("layouts", name.to_s), :preferred_engine => preferred_engine)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Check root, no preference
|
|
||||||
if !layout_path
|
|
||||||
layout_path, *etc = self.class.resolve_template(app, name)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Check layouts folder, no preference
|
|
||||||
if !layout_path
|
|
||||||
layout_path, *etc = self.class.resolve_template(app, File.join("layouts", name.to_s))
|
|
||||||
end
|
|
||||||
|
|
||||||
layout_path
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.resolve_template(app, 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
|
|
||||||
|
|
||||||
if matched_exts.length > 0
|
|
||||||
preferred_engine = "{" + matched_exts.join(",") + "}"
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
path_with_ext = on_disk_path + "." + preferred_engine
|
|
||||||
found_path = Dir[path_with_ext].find do |path|
|
|
||||||
::Tilt[path]
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def internal_render(path, locs = {}, opts = {}, &block)
|
|
||||||
path = path.to_s
|
|
||||||
body = app.cache.fetch(:raw_template, path) do
|
|
||||||
File.read(path)
|
|
||||||
end
|
|
||||||
|
|
||||||
self.class.static_render(app, path, body, locs, opts, &block)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.static_render(app, path, body, locs = {}, opts = {}, &block)
|
|
||||||
options = opts.merge(options_for_ext(File.extname(path)))
|
|
||||||
|
|
||||||
template = cache.fetch(:compiled_template, options, body) do
|
|
||||||
::Tilt.new(path, 1, options) { body }
|
|
||||||
end
|
|
||||||
|
|
||||||
template.render(app, locs, &block)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
Loading…
Reference in a new issue