move rendering into rendering extension, instead of sitemap
This commit is contained in:
parent
7c50c9e4d5
commit
fed3dd5a85
3 changed files with 206 additions and 195 deletions
|
@ -176,15 +176,15 @@ class Middleman::Base
|
|||
# Add Guard Callbacks
|
||||
register Middleman::CoreExtensions::FileWatcher
|
||||
|
||||
# Sitemap
|
||||
register Middleman::CoreExtensions::Sitemap
|
||||
|
||||
# Activate Data package
|
||||
register Middleman::CoreExtensions::Data
|
||||
|
||||
# Setup custom rendering
|
||||
register Middleman::CoreExtensions::Rendering
|
||||
|
||||
# Sitemap
|
||||
register Middleman::CoreExtensions::Sitemap
|
||||
|
||||
# Compass framework
|
||||
register Middleman::CoreExtensions::Compass
|
||||
|
||||
|
@ -231,6 +231,8 @@ class Middleman::Base
|
|||
# Current path defaults to nil, used in views.
|
||||
@current_path = nil
|
||||
|
||||
cache.clear
|
||||
|
||||
# Setup the default values from calls to set before initialization
|
||||
self.class.superclass.defaults.each { |k,v| set k,v }
|
||||
|
||||
|
@ -250,10 +252,18 @@ class Middleman::Base
|
|||
#
|
||||
# @private
|
||||
# @return [Middleman::Cache] The cache
|
||||
def cache
|
||||
def self.cache
|
||||
@_cache ||= ::Middleman::Cache.new
|
||||
end
|
||||
|
||||
# Cache accessor for instance, simply forwards to class
|
||||
#
|
||||
# @private
|
||||
# @return [Middleman::Cache] The cache
|
||||
def cache
|
||||
self.class.cache
|
||||
end
|
||||
|
||||
# Rack env
|
||||
attr :env
|
||||
|
||||
|
@ -334,7 +344,7 @@ class Middleman::Base
|
|||
|
||||
# Valid content is a 200 status
|
||||
res.status = 200
|
||||
rescue ::Middleman::Sitemap::TemplateNotFound => e
|
||||
rescue Middleman::CoreExtensions::Rendering::TemplateNotFound => e
|
||||
res.write "Error: #{e.message}"
|
||||
res.status = 500
|
||||
end
|
||||
|
@ -372,54 +382,6 @@ class Middleman::Base
|
|||
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
|
||||
#
|
||||
# @param [Symbol] File extension
|
||||
|
|
|
@ -9,6 +9,8 @@ module Middleman::CoreExtensions::Rendering
|
|||
rescue LoadError
|
||||
end
|
||||
|
||||
app.send :include, InstanceMethods
|
||||
|
||||
# Activate custom renderers
|
||||
app.register Middleman::Renderers::Sass
|
||||
app.register Middleman::Renderers::Markdown
|
||||
|
@ -17,4 +19,191 @@ module Middleman::CoreExtensions::Rendering
|
|||
end
|
||||
alias :included :registered
|
||||
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
|
|
@ -1,7 +1,5 @@
|
|||
module Middleman::Sitemap
|
||||
class TemplateNotFound < RuntimeError
|
||||
end
|
||||
|
||||
|
||||
class Template
|
||||
attr_accessor :page, :options, :locals, :blocks#, :dependencies
|
||||
|
||||
|
@ -53,14 +51,7 @@ module Middleman::Sitemap
|
|||
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
|
||||
app.render_template(source_file, locs, opts)
|
||||
end
|
||||
|
||||
protected
|
||||
|
@ -71,136 +62,5 @@ module Middleman::Sitemap
|
|||
def cache
|
||||
self.class.cache
|
||||
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
|
Loading…
Reference in a new issue