Merge pull request #1138 from middleman/template_jail
Put template rendering in a jail
This commit is contained in:
commit
09c7bda6b1
|
@ -10,6 +10,7 @@ matrix:
|
|||
fast_finish: true
|
||||
allow_failures:
|
||||
- rvm: ruby-head
|
||||
- rvm: 2.1.0
|
||||
- rvm: jruby-19mode
|
||||
env: TEST=true
|
||||
before_install: git submodule update --init --recursive
|
||||
|
|
|
@ -44,15 +44,6 @@ module Middleman
|
|||
# Runs after the build is finished
|
||||
define_hook :after_build
|
||||
|
||||
# Mix-in helper methods. Accepts either a list of Modules
|
||||
# and/or a block to be evaluated
|
||||
# @return [void]
|
||||
def self.helpers(*extensions, &block)
|
||||
class_eval(&block) if block_given?
|
||||
include(*extensions) if extensions.any?
|
||||
end
|
||||
delegate :helpers, :to => :"self.class"
|
||||
|
||||
# Root project directory (overwritten in middleman build/server)
|
||||
# @return [String]
|
||||
def self.root
|
||||
|
@ -170,11 +161,16 @@ module Middleman
|
|||
# Template cache
|
||||
attr_reader :cache
|
||||
|
||||
attr_reader :generic_template_context
|
||||
delegate :link_to, :image_tag, :to => :generic_template_context
|
||||
|
||||
# Initialize the Middleman project
|
||||
def initialize(&block)
|
||||
@cache = ::Tilt::Cache.new
|
||||
@logger = ::Middleman::Logger.singleton
|
||||
@config_context = ConfigContext.new(self)
|
||||
@template_context_class = Class.new(Middleman::TemplateContext)
|
||||
@generic_template_context = @template_context_class.new(self)
|
||||
@config_context = ConfigContext.new(self, @template_context_class)
|
||||
|
||||
# Setup the default values from calls to set before initialization
|
||||
self.class.config.load_settings(self.class.superclass.config.all_settings)
|
||||
|
|
|
@ -6,16 +6,32 @@ module Middleman
|
|||
attr_reader :app
|
||||
|
||||
# Whitelist methods that can reach out.
|
||||
delegate :config, :logger, :activate, :use, :map, :mime_type, :data, :helpers, :template_extensions, :root, :to => :app
|
||||
delegate :config, :logger, :activate, :use, :map, :mime_type, :data, :template_extensions, :root, :to => :app
|
||||
|
||||
def initialize(app)
|
||||
def initialize(app, template_context_class)
|
||||
@app = app
|
||||
@template_context_class = template_context_class
|
||||
|
||||
@ready_callbacks = []
|
||||
@after_build_callbacks = []
|
||||
@after_configuration_callbacks = []
|
||||
@configure_callbacks = {}
|
||||
end
|
||||
|
||||
def helpers(*helper_modules, &block)
|
||||
helper_modules ||= []
|
||||
|
||||
if block_given?
|
||||
block_module = Module.new
|
||||
block_module.module_eval(&block)
|
||||
helper_modules << block_module
|
||||
end
|
||||
|
||||
helper_modules.each do |mod|
|
||||
@template_context_class.send :include, mod
|
||||
end
|
||||
end
|
||||
|
||||
def ready(&block)
|
||||
@ready_callbacks << block
|
||||
end
|
||||
|
|
|
@ -182,6 +182,11 @@ module Middleman
|
|||
end
|
||||
|
||||
if klass.is_a?(::Middleman::Extension)
|
||||
# Forward Extension helpers to TemplateContext
|
||||
(klass.class.defined_helpers || []).each do |m|
|
||||
@template_context_class.send(:include, m)
|
||||
end
|
||||
|
||||
::Middleman::Extension.activated_extension(klass)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,7 +24,7 @@ module Middleman
|
|||
require filename
|
||||
next unless Object.const_defined?(module_name.to_sym)
|
||||
|
||||
helpers Object.const_get(module_name.to_sym)
|
||||
@template_context_class.send :include, Object.const_get(module_name.to_sym)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -81,13 +81,11 @@ module Middleman::CoreExtensions
|
|||
end
|
||||
end
|
||||
|
||||
helpers do
|
||||
# Get the template data from a path
|
||||
# @param [String] path
|
||||
# @return [String]
|
||||
def template_data_for_file(path)
|
||||
extensions[:frontmatter].data(path).last
|
||||
end
|
||||
# Get the template data from a path
|
||||
# @param [String] path
|
||||
# @return [String]
|
||||
def template_data_for_file(path)
|
||||
data(path).last
|
||||
end
|
||||
|
||||
def data(path)
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
# Shutup Tilt Warnings
|
||||
# @private
|
||||
class Tilt::Template
|
||||
def warn(*args)
|
||||
# Kernel.warn(*args)
|
||||
end
|
||||
end
|
||||
require 'middleman-core/template_context'
|
||||
|
||||
# Rendering extension
|
||||
module Middleman
|
||||
|
||||
module CoreExtensions
|
||||
module Rendering
|
||||
|
||||
|
@ -136,16 +131,17 @@ module Middleman
|
|||
::I18n.locale = opts[:lang] if opts[:lang]
|
||||
end
|
||||
|
||||
# Use a dup of self as a context so that instance variables set within
|
||||
# the template don't persist for other templates.
|
||||
context = self.dup
|
||||
# Sandboxed class for template eval
|
||||
context = @template_context_class.new(self, locs, opts)
|
||||
|
||||
if context.respond_to?(:init_haml_helpers)
|
||||
context.init_haml_helpers
|
||||
end
|
||||
|
||||
blocks.each do |block|
|
||||
context.instance_eval(&block)
|
||||
end
|
||||
|
||||
# Store current locs/opts for later
|
||||
@current_locs = locs, @current_opts = opts
|
||||
|
||||
# Keep rendering template until we've used up all extensions. This
|
||||
# handles cases like `style.css.sass.erb`
|
||||
content = nil
|
||||
|
@ -170,60 +166,6 @@ module Middleman
|
|||
# Pop all the saved variables from earlier as we may be returning to a
|
||||
# previous render (layouts, partials, nested layouts).
|
||||
::I18n.locale = old_locale if defined?(::I18n)
|
||||
@content_blocks = nil
|
||||
@current_locs = nil
|
||||
@current_opts = nil
|
||||
end
|
||||
|
||||
# Sinatra/Padrino compatible render method signature referenced by some view
|
||||
# helpers. Especially partials.
|
||||
#
|
||||
# @param [String, Symbol] engine
|
||||
# @param [String, Symbol] data
|
||||
# @param [Hash] options
|
||||
# @return [String]
|
||||
def render(engine, data, options={}, &block)
|
||||
data = data.to_s
|
||||
|
||||
locals = options[:locals]
|
||||
|
||||
found_partial = false
|
||||
engine = nil
|
||||
|
||||
# If the path is known to the sitemap
|
||||
if resource = sitemap.find_resource_by_path(current_path)
|
||||
current_dir = File.dirname(resource.source_file)
|
||||
engine = File.extname(resource.source_file)[1..-1].to_sym
|
||||
|
||||
# Look for partials relative to the current path
|
||||
relative_dir = File.join(current_dir.sub(%r{^#{Regexp.escape(self.source_dir)}/?}, ''), data)
|
||||
|
||||
# Try to use the current engine first
|
||||
found_partial, found_engine = resolve_template(relative_dir, :preferred_engine => engine, :try_without_underscore => true)
|
||||
|
||||
# Fall back to any engine available
|
||||
if !found_partial
|
||||
found_partial, found_engine = resolve_template(relative_dir, :try_without_underscore => true)
|
||||
end
|
||||
end
|
||||
|
||||
# Look in the partials_dir for the partial with the current engine
|
||||
partials_path = File.join(config[:partials_dir], data)
|
||||
if !found_partial && !engine.nil?
|
||||
found_partial, found_engine = resolve_template(partials_path, :preferred_engine => engine, :try_without_underscore => true)
|
||||
end
|
||||
|
||||
# Look in the root with any engine
|
||||
if !found_partial
|
||||
found_partial, found_engine = resolve_template(partials_path, :try_without_underscore => true)
|
||||
end
|
||||
|
||||
# Render the partial if found, otherwide throw exception
|
||||
if found_partial
|
||||
render_individual_file(found_partial, locals, options, self, &block)
|
||||
else
|
||||
raise ::Middleman::CoreExtensions::Rendering::TemplateNotFound, "Could not locate partial: #{data}"
|
||||
end
|
||||
end
|
||||
|
||||
# Render an on-disk file. Used for everything, including layouts.
|
||||
|
@ -233,7 +175,7 @@ module Middleman
|
|||
# @param [Hash] opts
|
||||
# @param [Class] context
|
||||
# @return [String]
|
||||
def render_individual_file(path, locs = {}, opts = {}, context = self, &block)
|
||||
def render_individual_file(path, locs = {}, opts = {}, context, &block)
|
||||
path = path.to_s
|
||||
|
||||
# Detect the remdering engine from the extension
|
||||
|
@ -244,7 +186,7 @@ module Middleman
|
|||
context.current_engine, engine_was = engine, context.current_engine
|
||||
|
||||
# Save current buffer for later
|
||||
@_out_buf, _buf_was = '', @_out_buf
|
||||
_buf_was = context.save_buffer
|
||||
|
||||
# Read from disk or cache the contents of the file
|
||||
body = if opts[:template_body]
|
||||
|
@ -287,7 +229,7 @@ module Middleman
|
|||
output
|
||||
ensure
|
||||
# Reset stored buffer
|
||||
@_out_buf = _buf_was
|
||||
context.restore_buffer(_buf_was)
|
||||
context.current_engine = engine_was
|
||||
end
|
||||
|
||||
|
@ -295,7 +237,11 @@ module Middleman
|
|||
# @param [String] path
|
||||
# @return [String]
|
||||
def template_data_for_file(path)
|
||||
File.read(File.expand_path(path, source_dir))
|
||||
if extensions[:frontmatter]
|
||||
extensions[:frontmatter].template_data_for_file(path)
|
||||
else
|
||||
File.read(File.expand_path(path, source_dir))
|
||||
end
|
||||
end
|
||||
|
||||
# Get a hash of configuration options for a given file extension, from
|
||||
|
@ -393,49 +339,6 @@ module Middleman
|
|||
layout_path
|
||||
end
|
||||
|
||||
# Allow layouts to be wrapped in the contents of other layouts
|
||||
# @param [String, Symbol] layout_name
|
||||
# @return [void]
|
||||
def wrap_layout(layout_name, &block)
|
||||
# Save current buffer for later
|
||||
@_out_buf, _buf_was = '', @_out_buf
|
||||
|
||||
layout_path = locate_layout(layout_name, self.current_engine)
|
||||
|
||||
extension = File.extname(layout_path)
|
||||
engine = extension[1..-1].to_sym
|
||||
|
||||
# Store last engine for later (could be inside nested renders)
|
||||
self.current_engine, engine_was = engine, self.current_engine
|
||||
|
||||
begin
|
||||
content = if block_given?
|
||||
capture_html(&block)
|
||||
else
|
||||
''
|
||||
end
|
||||
ensure
|
||||
# Reset stored buffer
|
||||
@_out_buf = _buf_was
|
||||
end
|
||||
|
||||
concat_safe_content render_individual_file(layout_path, @current_locs || {}, @current_opts || {}, self) { content }
|
||||
ensure
|
||||
self.current_engine = engine_was
|
||||
end
|
||||
|
||||
# The currently rendering engine
|
||||
# @return [Symbol, nil]
|
||||
def current_engine
|
||||
@_current_engine ||= nil
|
||||
end
|
||||
|
||||
# The currently rendering engine
|
||||
# @return [Symbol, nil]
|
||||
def current_engine=(v)
|
||||
@_current_engine = v
|
||||
end
|
||||
|
||||
# Find a template on disk given a output path
|
||||
# @param [String] request_path
|
||||
# @param [Hash] options
|
||||
|
|
|
@ -20,7 +20,7 @@ module Middleman
|
|||
def helpers(*m, &block)
|
||||
self.defined_helpers ||= []
|
||||
|
||||
if block
|
||||
if block_given?
|
||||
mod = Module.new
|
||||
mod.module_eval(&block)
|
||||
m = [mod]
|
||||
|
@ -81,8 +81,11 @@ module Middleman
|
|||
def app=(app)
|
||||
@app = app
|
||||
|
||||
(self.class.defined_helpers || []).each do |m|
|
||||
app.class.send(:include, m)
|
||||
ext = self
|
||||
if ext.respond_to?(:instance_available)
|
||||
@klass.instance_available do
|
||||
ext.instance_available
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -4,24 +4,42 @@ require 'haml'
|
|||
module Middleman
|
||||
module Renderers
|
||||
|
||||
# Haml precompiles filters before the scope is even available,
|
||||
# thus making it impossible to pass our Middleman instance
|
||||
# in. So we have to resort to heavy hackery :(
|
||||
class HamlTemplate < ::Tilt::HamlTemplate
|
||||
def prepare
|
||||
end
|
||||
|
||||
def evaluate(scope, locals, &block)
|
||||
::Middleman::Renderers::Haml.last_haml_scope = scope
|
||||
|
||||
options = @options.merge(:filename => eval_file, :line => line)
|
||||
@engine = ::Haml::Engine.new(data, options)
|
||||
output = @engine.render(scope, locals, &block)
|
||||
|
||||
::Middleman::Renderers::Haml.last_haml_scope = nil
|
||||
|
||||
output
|
||||
end
|
||||
end
|
||||
|
||||
# Haml Renderer
|
||||
module Haml
|
||||
mattr_accessor :last_haml_scope
|
||||
|
||||
# Setup extension
|
||||
class << self
|
||||
# Once registered
|
||||
def registered(app)
|
||||
::Tilt.prefer(::Middleman::Renderers::HamlTemplate, 'haml')
|
||||
|
||||
app.before_configuration do
|
||||
template_extensions :haml => :html
|
||||
end
|
||||
|
||||
# Add haml helpers to context
|
||||
app.send :include, ::Haml::Helpers
|
||||
|
||||
# Setup haml helper paths
|
||||
app.ready do
|
||||
init_haml_helpers
|
||||
end
|
||||
::Middleman::TemplateContext.send :include, ::Haml::Helpers
|
||||
end
|
||||
alias :included :registered
|
||||
end
|
||||
|
|
|
@ -7,6 +7,8 @@ module Middleman
|
|||
class KramdownTemplate < ::Tilt::KramdownTemplate
|
||||
def evaluate(scope, locals, &block)
|
||||
@output ||= begin
|
||||
MiddlemanKramdownHTML.scope = ::Middleman::Renderers::Haml.last_haml_scope || scope
|
||||
|
||||
output, warnings = MiddlemanKramdownHTML.convert(@engine.root, @engine.options)
|
||||
@engine.warnings.concat(warnings)
|
||||
output
|
||||
|
@ -16,13 +18,13 @@ module Middleman
|
|||
|
||||
# Custom Kramdown renderer that uses our helpers for images and links
|
||||
class MiddlemanKramdownHTML < ::Kramdown::Converter::Html
|
||||
cattr_accessor :middleman_app
|
||||
cattr_accessor :scope
|
||||
|
||||
def convert_img(el, indent)
|
||||
attrs = el.attr.dup
|
||||
|
||||
link = attrs.delete('src')
|
||||
middleman_app.image_tag(link, attrs)
|
||||
scope.image_tag(link, attrs)
|
||||
end
|
||||
|
||||
def convert_a(el, indent)
|
||||
|
@ -37,7 +39,7 @@ module Middleman
|
|||
|
||||
attr = el.attr.dup
|
||||
link = attr.delete('href')
|
||||
middleman_app.link_to(content, link, attr)
|
||||
scope.link_to(content, link, attr)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,11 +30,9 @@ module Middleman
|
|||
if config[:markdown_engine] == :redcarpet
|
||||
require 'middleman-core/renderers/redcarpet'
|
||||
::Tilt.prefer(::Middleman::Renderers::RedcarpetTemplate, *markdown_exts)
|
||||
MiddlemanRedcarpetHTML.middleman_app = self
|
||||
elsif config[:markdown_engine] == :kramdown
|
||||
require 'middleman-core/renderers/kramdown'
|
||||
::Tilt.prefer(::Middleman::Renderers::KramdownTemplate, *markdown_exts)
|
||||
MiddlemanKramdownHTML.middleman_app = self
|
||||
elsif !config[:markdown_engine].nil?
|
||||
# Map symbols to classes
|
||||
markdown_engine_klass = if config[:markdown_engine].is_a? Symbol
|
||||
|
|
|
@ -40,6 +40,14 @@ module Middleman
|
|||
renderer.new(render_options)
|
||||
end
|
||||
|
||||
def evaluate(scope, locals, &block)
|
||||
@output ||= begin
|
||||
MiddlemanRedcarpetHTML.scope = ::Middleman::Renderers::Haml.last_haml_scope || scope
|
||||
|
||||
@engine.render(data)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def covert_options_to_aliases!
|
||||
|
@ -51,7 +59,7 @@ module Middleman
|
|||
|
||||
# Custom Redcarpet renderer that uses our helpers for images and links
|
||||
class MiddlemanRedcarpetHTML < ::Redcarpet::Render::HTML
|
||||
cattr_accessor :middleman_app
|
||||
cattr_accessor :scope
|
||||
|
||||
def initialize(options={})
|
||||
@local_options = options.dup
|
||||
|
@ -61,7 +69,7 @@ module Middleman
|
|||
|
||||
def image(link, title, alt_text)
|
||||
if !@local_options[:no_images]
|
||||
middleman_app.image_tag(link, :title => title, :alt => alt_text)
|
||||
scope.image_tag(link, :title => title, :alt => alt_text)
|
||||
else
|
||||
link_string = link.dup
|
||||
link_string << %Q{"#{title}"} if title && title.length > 0 && title != alt_text
|
||||
|
@ -74,7 +82,7 @@ module Middleman
|
|||
attributes = { :title => title }
|
||||
attributes.merge!( @local_options[:link_attributes] ) if @local_options[:link_attributes]
|
||||
|
||||
middleman_app.link_to(content, link, attributes )
|
||||
scope.link_to(content, link, attributes )
|
||||
else
|
||||
link_string = link.dup
|
||||
link_string << %Q{"#{title}"} if title && title.length > 0 && title != alt_text
|
||||
|
|
|
@ -74,7 +74,7 @@ module Middleman
|
|||
def sass_options
|
||||
more_opts = { :filename => eval_file, :line => line, :syntax => syntax }
|
||||
|
||||
if @context.is_a?(::Middleman::Application) && file
|
||||
if @context.is_a?(::Middleman::TemplateContext) && file
|
||||
location_of_sass_file = @context.source_dir
|
||||
|
||||
parts = basename.split('.')
|
||||
|
|
|
@ -31,7 +31,7 @@ module Middleman
|
|||
}, 'Callbacks that can exclude paths from the sitemap'
|
||||
|
||||
# Include instance methods
|
||||
app.send :include, InstanceMethods
|
||||
::Middleman::TemplateContext.send :include, InstanceMethods
|
||||
end
|
||||
|
||||
end
|
||||
|
|
105
middleman-core/lib/middleman-core/template_context.rb
Normal file
105
middleman-core/lib/middleman-core/template_context.rb
Normal file
|
@ -0,0 +1,105 @@
|
|||
module Middleman
|
||||
class TemplateContext
|
||||
attr_reader :app
|
||||
attr_accessor :current_engine, :current_path
|
||||
|
||||
delegate :config, :logger, :sitemap, :build?, :development?, :data, :extensions, :source_dir, :root, :to => :app
|
||||
|
||||
def initialize(app, locs={}, opts={})
|
||||
@app = app
|
||||
@current_locs = locs
|
||||
@current_opts = opts
|
||||
end
|
||||
|
||||
def save_buffer
|
||||
@_out_buf, _buf_was = '', @_out_buf
|
||||
_buf_was
|
||||
end
|
||||
|
||||
def restore_buffer(_buf_was)
|
||||
@_out_buf = _buf_was
|
||||
end
|
||||
|
||||
# Allow layouts to be wrapped in the contents of other layouts
|
||||
# @param [String, Symbol] layout_name
|
||||
# @return [void]
|
||||
def wrap_layout(layout_name, &block)
|
||||
# Save current buffer for later
|
||||
_buf_was = save_buffer
|
||||
|
||||
layout_path = @app.locate_layout(layout_name, self.current_engine)
|
||||
|
||||
extension = File.extname(layout_path)
|
||||
engine = extension[1..-1].to_sym
|
||||
|
||||
# Store last engine for later (could be inside nested renders)
|
||||
self.current_engine, engine_was = engine, self.current_engine
|
||||
|
||||
begin
|
||||
content = if block_given?
|
||||
capture_html(&block)
|
||||
else
|
||||
''
|
||||
end
|
||||
ensure
|
||||
# Reset stored buffer
|
||||
restore_buffer(_buf_was)
|
||||
end
|
||||
|
||||
concat_safe_content @app.render_individual_file(layout_path, @current_locs || {}, @current_opts || {}, self) { content }
|
||||
ensure
|
||||
self.current_engine = engine_was
|
||||
end
|
||||
|
||||
# Sinatra/Padrino compatible render method signature referenced by some view
|
||||
# helpers. Especially partials.
|
||||
#
|
||||
# @param [String, Symbol] engine
|
||||
# @param [String, Symbol] data
|
||||
# @param [Hash] options
|
||||
# @return [String]
|
||||
def render(engine, data, options={}, &block)
|
||||
data = data.to_s
|
||||
|
||||
locals = options[:locals]
|
||||
|
||||
found_partial = false
|
||||
engine = nil
|
||||
|
||||
# If the path is known to the sitemap
|
||||
if resource = sitemap.find_resource_by_path(current_path)
|
||||
current_dir = File.dirname(resource.source_file)
|
||||
engine = File.extname(resource.source_file)[1..-1].to_sym
|
||||
|
||||
# Look for partials relative to the current path
|
||||
relative_dir = File.join(current_dir.sub(%r{^#{Regexp.escape(self.source_dir)}/?}, ''), data)
|
||||
|
||||
# Try to use the current engine first
|
||||
found_partial, found_engine = @app.resolve_template(relative_dir, :preferred_engine => engine, :try_without_underscore => true)
|
||||
|
||||
# Fall back to any engine available
|
||||
if !found_partial
|
||||
found_partial, found_engine = @app.resolve_template(relative_dir, :try_without_underscore => true)
|
||||
end
|
||||
end
|
||||
|
||||
# Look in the partials_dir for the partial with the current engine
|
||||
partials_path = File.join(config[:partials_dir], data)
|
||||
if !found_partial && !engine.nil?
|
||||
found_partial, found_engine = @app.resolve_template(partials_path, :preferred_engine => engine, :try_without_underscore => true)
|
||||
end
|
||||
|
||||
# Look in the root with any engine
|
||||
if !found_partial
|
||||
found_partial, found_engine = @app.resolve_template(partials_path, :try_without_underscore => true)
|
||||
end
|
||||
|
||||
# Render the partial if found, otherwide throw exception
|
||||
if found_partial
|
||||
@app.render_individual_file(found_partial, locals, options, self, &block)
|
||||
else
|
||||
raise ::Middleman::CoreExtensions::Rendering::TemplateNotFound, "Could not locate partial: #{data}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -21,15 +21,15 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension
|
|||
|
||||
require 'active_support/core_ext/object/to_query'
|
||||
|
||||
app.helpers ::Padrino::Helpers::OutputHelpers
|
||||
app.helpers ::Padrino::Helpers::TagHelpers
|
||||
app.helpers ::Padrino::Helpers::AssetTagHelpers
|
||||
app.helpers ::Padrino::Helpers::FormHelpers
|
||||
app.helpers ::Padrino::Helpers::FormatHelpers
|
||||
app.helpers ::Padrino::Helpers::RenderHelpers
|
||||
app.helpers ::Padrino::Helpers::NumberHelpers
|
||||
# app.helpers ::Padrino::Helpers::TranslationHelpers
|
||||
app.helpers ::Padrino::Helpers::Breadcrumbs
|
||||
::Middleman::TemplateContext.send :include, ::Padrino::Helpers::OutputHelpers
|
||||
::Middleman::TemplateContext.send :include, ::Padrino::Helpers::TagHelpers
|
||||
::Middleman::TemplateContext.send :include, ::Padrino::Helpers::AssetTagHelpers
|
||||
::Middleman::TemplateContext.send :include, ::Padrino::Helpers::FormHelpers
|
||||
::Middleman::TemplateContext.send :include, ::Padrino::Helpers::FormatHelpers
|
||||
::Middleman::TemplateContext.send :include, ::Padrino::Helpers::RenderHelpers
|
||||
::Middleman::TemplateContext.send :include, ::Padrino::Helpers::NumberHelpers
|
||||
# ::Middleman::TemplateContext.send :include, ::Padrino::Helpers::TranslationHelpers
|
||||
::Middleman::TemplateContext.send :include, ::Padrino::Helpers::Breadcrumbs
|
||||
|
||||
app.config.define_setting :relative_links, false, 'Whether to generate relative links instead of absolute ones'
|
||||
end
|
||||
|
@ -39,6 +39,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension
|
|||
|
||||
# Make all block content html_safe
|
||||
def content_tag(name, content = nil, options = nil, &block)
|
||||
# safe_content_tag(name, content, options, &block)
|
||||
if block_given?
|
||||
options = content if content.is_a?(Hash)
|
||||
content = capture_html(&block)
|
||||
|
@ -61,17 +62,23 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension
|
|||
def capture_html(*args, &block)
|
||||
handler = auto_find_proper_handler(&block)
|
||||
captured_block, captured_html = nil, ''
|
||||
if handler && handler.is_type? && handler.block_is_type?(block)
|
||||
|
||||
if handler && handler.block_is_type?(block)
|
||||
captured_html, captured_block = handler.capture_from_template(*args, &block)
|
||||
end
|
||||
|
||||
# invoking the block directly if there was no template
|
||||
captured_html = block_given? && ( captured_block || block.call(*args) ) if captured_html.blank?
|
||||
captured_html = block_given? && ( captured_block || block.call(*args) ) if captured_html.blank?
|
||||
captured_html
|
||||
end
|
||||
|
||||
def auto_find_proper_handler(&block)
|
||||
engine = block_given? ? File.extname(block.source_location[0])[1..-1].to_sym : current_engine
|
||||
::Padrino::Helpers::OutputHelpers.handlers.map { |h| h.new(self) }.find { |h| h.engines.include?(engine) && h.is_type? }
|
||||
if block_given?
|
||||
engine = File.extname(block.source_location[0])[1..-1].to_sym
|
||||
::Padrino::Helpers::OutputHelpers.handlers.map { |h| h.new(self) }.find { |h| h.engines.include?(engine) && h.block_is_type?(block) }
|
||||
else
|
||||
find_proper_handler
|
||||
end
|
||||
end
|
||||
|
||||
# Disable Padrino cache buster
|
||||
|
@ -197,7 +204,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension
|
|||
options_with_resource = options.dup
|
||||
options_with_resource[:current_resource] ||= current_resource
|
||||
|
||||
::Middleman::Util.url_for(self, path_or_resource, options_with_resource)
|
||||
::Middleman::Util.url_for(app, path_or_resource, options_with_resource)
|
||||
end
|
||||
|
||||
# Overload the regular link_to to be sitemap-aware - if you
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
class Middleman::Extensions::Gzip < ::Middleman::Extension
|
||||
option :exts, %w(.js .css .html .htm), 'File extensions to Gzip when building.'
|
||||
|
||||
class NumberHelpers
|
||||
include ::Padrino::Helpers::NumberHelpers
|
||||
end
|
||||
|
||||
def initialize(app, options_hash={})
|
||||
super
|
||||
|
||||
|
@ -57,11 +61,11 @@ class Middleman::Extensions::Gzip < ::Middleman::Extension
|
|||
if output_filename
|
||||
total_savings += (old_size - new_size)
|
||||
size_change_word = (old_size - new_size) > 0 ? 'smaller' : 'larger'
|
||||
builder.say_status :gzip, "#{output_filename} (#{app.number_to_human_size((old_size - new_size).abs)} #{size_change_word})"
|
||||
builder.say_status :gzip, "#{output_filename} (#{NumberHelpers.new.number_to_human_size((old_size - new_size).abs)} #{size_change_word})"
|
||||
end
|
||||
end
|
||||
|
||||
builder.say_status :gzip, "Total gzip savings: #{app.number_to_human_size(total_savings)}", :blue
|
||||
builder.say_status :gzip, "Total gzip savings: #{NumberHelpers.new.number_to_human_size(total_savings)}", :blue
|
||||
I18n.locale = old_locale
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue