Skip to content

Commit

Permalink
Merge pull request #1441 from padrino/fix-output-handlers
Browse files Browse the repository at this point in the history
Fix and cleanup output handlers
  • Loading branch information
ujifgc committed Oct 10, 2013
2 parents 3f37312 + 80a0e24 commit 8bb8124
Show file tree
Hide file tree
Showing 27 changed files with 121 additions and 210 deletions.
4 changes: 1 addition & 3 deletions padrino-helpers/lib/padrino-helpers/form_helpers.rb
Expand Up @@ -90,9 +90,7 @@ def form_tag(url, options={}, &block)
inner_form_html << csrf_token_field
end
inner_form_html << mark_safe(capture_html(&block))
not_concat = options.delete(:not_concat)
form_html = content_tag(:form, inner_form_html, options)
not_concat ? form_html : concat_content(form_html)
concat_content content_tag(:form, inner_form_html, options)
end

##
Expand Down
21 changes: 9 additions & 12 deletions padrino-helpers/lib/padrino-helpers/output_helpers.rb
Expand Up @@ -45,14 +45,11 @@ def render(engine, *)
# # => "<foo>"
#
def capture_html(*args, &block)
handler = find_proper_handler
captured_block, captured_html = nil, ""
if handler && handler.is_type? && handler.block_is_type?(block)
captured_html, captured_block = handler.capture_from_template(*args, &block)
if handler = find_proper_handler
handler.capture_from_template(*args, &block)
else
block.call(*args)
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
end
alias :capture :capture_html

Expand All @@ -68,10 +65,9 @@ def capture_html(*args, &block)
# concat_content("This will be output to the template buffer")
#
def concat_content(text="")
handler = find_proper_handler
if handler && handler.is_type?
if handler = find_proper_handler
handler.concat_to_template(text)
else # theres no template to concat, return the text directly
else
text
end
end
Expand Down Expand Up @@ -105,7 +101,7 @@ def concat_safe_content(text="")
#
def block_is_template?(block)
handler = find_proper_handler
block && handler && handler.block_is_type?(block)
block && handler && handler.engine_matches?(block)
end

##
Expand Down Expand Up @@ -185,7 +181,8 @@ def content_blocks
# find_proper_handler => <OutputHelpers::HamlHandler>
#
def find_proper_handler
OutputHelpers.handlers.map { |h| h.new(self) }.find { |h| h.engines.include?(current_engine) && h.is_type? }
handler_class = OutputHelpers.handlers[current_engine]
handler_class && handler_class.new(self)
end

##
Expand Down
Expand Up @@ -8,7 +8,7 @@ module OutputHelpers
# OutputHelpers.handlers => [<OutputHelpers::HamlHandler>, <OutputHelpers::ErbHandler>]
#
def self.handlers
@_template_handlers ||= []
@_template_handlers ||= {}
end

##
Expand All @@ -17,8 +17,8 @@ def self.handlers
# @example
# OutputHelpers.register(OutputHelpers::HamlHandler)
#
def self.register(handler)
handlers << handler
def self.register(engine, handler)
handlers[engine] = handler
end

# @abstract Extend this to create a template handler.
Expand All @@ -41,33 +41,13 @@ def template_extension
# => "erb"
end

##
# Returns an array of engines used for the template.
#
# @example
# @handler.engines => [:erb, :erubis]
#
def engines
# Implemented in subclass.
end

##
# Returns true if the current template type is same as this handlers; false otherwise.
#
# @example
# @handler.is_type? => true
#
def is_type?
# Implemented in subclass.
end

##
# Returns true if the block given is of the handler's template type; false otherwise.
#
# @example
# @handler.block_is_type?(block) => true
# @handler.engine_matches?(block) => true
#
def block_is_type?(block)
def engine_matches?(block)
# Implemented in subclass.
end

Expand All @@ -84,11 +64,15 @@ def capture_from_template(*args, &block)
##
# Outputs the given text to the templates buffer directly.
#
# This method is called when template uses block-aware helpers. For Slim and Haml such
# helpers just return output to use with `=`. For Erb this method is implemented in
# ErbHandler by concatenating text captured from the block to output buffer.
#
# @example
# @handler.concat_to_template("This will be output to the template buffer")
#
def concat_to_template(text="")
# Implemented in subclass.
text
end
end
end
Expand Down
38 changes: 10 additions & 28 deletions padrino-helpers/lib/padrino-helpers/output_helpers/erb_handler.rb
Expand Up @@ -12,16 +12,6 @@ def initialize(template)
@output_buffer = template.instance_variable_get(:@_out_buf)
end

##
# Returns true if the current template type is same as this handlers; false otherwise.
#
# @example
# @handler.is_type? => true
#
def is_type?
!self.output_buffer.nil?
end

##
# Captures the html from a block of template code for this handler.
#
Expand All @@ -30,10 +20,10 @@ def is_type?
#
def capture_from_template(*args, &block)
self.output_buffer, _buf_was = ActiveSupport::SafeBuffer.new, self.output_buffer
captured_block = block.call(*args)
ret = eval("@_out_buf", block.binding)
raw = block.call(*args)
captured = template.instance_variable_get(:@_out_buf)
self.output_buffer = _buf_was
[ ret, captured_block ]
engine_matches?(block) ? captured : raw
end

##
Expand All @@ -43,36 +33,28 @@ def capture_from_template(*args, &block)
# @handler.concat_to_template("This will be output to the template buffer")
#
def concat_to_template(text="")
self.output_buffer << text if is_type? && text
self.output_buffer << text if text
nil
end

##
# Returns true if the block given is of the handler's template type; false otherwise.
#
# @example
# @handler.block_is_type?(block) => true
# @handler.engine_matches?(block) => true
#
def block_is_type?(block)
block && eval('!!defined?(__in_erb_template)', block.binding)
end

##
# Returns an array of engines used for the template.
#
# @example
# @handler.engines => [:erb, :erubis]
#
def engines
@_engines ||= [:erb, :erubis]
def engine_matches?(block)
block.binding.eval('defined? __in_erb_template')
end

protected

def output_buffer=(val)
template.instance_variable_set(:@_out_buf, val)
end
end
OutputHelpers.register(ErbHandler)
OutputHelpers.register(:erb, ErbHandler)
OutputHelpers.register(:erubis, ErbHandler)
end
end
end
40 changes: 4 additions & 36 deletions padrino-helpers/lib/padrino-helpers/output_helpers/haml_handler.rb
Expand Up @@ -5,23 +5,13 @@ module OutputHelpers
# Handler for reading and writing from a haml template.
#
class HamlHandler < AbstractHandler
##
# Returns true if the current template type is same as this handlers; false otherwise.
#
# @example
# @handler.is_type? => true
#
def is_type?
template.respond_to?(:is_haml?) && template.is_haml?
end

##
# Returns true if the block given is of the handler's template type; false otherwise.
#
# @example
# @handler.block_is_type?(block) => true
# @handler.engine_matches?(block) => true
#
def block_is_type?(block)
def engine_matches?(block)
template.block_is_haml?(block)
end

Expand All @@ -32,32 +22,10 @@ def block_is_type?(block)
# @handler.capture_from_template(&block) => "...html..."
#
def capture_from_template(*args, &block)
eval("_hamlout ||= @haml_buffer", block.binding)
template.capture_haml(*args, &block)
end

##
# Outputs the given text to the templates buffer directly.
#
# @example
# @handler.concat_to_template("This will be output to the template buffer")
#
def concat_to_template(text="")
template.haml_concat(text)
nil
end

##
# Returns an array of engines used for the template.
#
# @example
# @handler.engines => [:haml]
#
def engines
@_engines ||= [:haml]
engine_matches?(block) ? template.capture_haml(*args, &block) : block.call(*args)
end
end
OutputHelpers.register(HamlHandler)
OutputHelpers.register(:haml, HamlHandler)
end
end
end
46 changes: 8 additions & 38 deletions padrino-helpers/lib/padrino-helpers/output_helpers/slim_handler.rb
Expand Up @@ -12,16 +12,6 @@ def initialize(template)
@output_buffer = template.instance_variable_get(:@_out_buf)
end

##
# Returns true if the current template type is same as this handlers; false otherwise.
#
# @example
# @handler.is_type? => true
#
def is_type?
!self.output_buffer.nil?
end

##
# Captures the html from a block of template code for this handler.
#
Expand All @@ -30,49 +20,29 @@ def is_type?
#
def capture_from_template(*args, &block)
self.output_buffer, _buf_was = ActiveSupport::SafeBuffer.new, self.output_buffer
captured_block = block.call(*args)
ret = eval("@_out_buf", block.binding)
raw = block.call(*args)
captured = template.instance_variable_get(:@_out_buf)
self.output_buffer = _buf_was
[ ret, captured_block ]
end

##
# Outputs the given text to the templates buffer directly.
#
# @example
# @handler.concat_to_template("This will be output to the template buffer")
#
def concat_to_template(text="")
self.output_buffer << text if is_type? && text
nil
engine_matches?(block) ? captured : raw
end

##
# Returns true if the block given is of the handler's template type; false otherwise.
#
# @example
# @handler.block_is_type?(block) => true
# @handler.engine_matches?(block) => true
#
def block_is_type?(block)
block && eval('defined? __in_slim_template', block.binding)
end

##
# Returns an array of engines used for the template.
#
# @example
# @handler.engines => [:erb, :erubis]
#
def engines
@_engines ||= [:slim]
def engine_matches?(block)
block.binding.eval('defined? __in_slim_template')
end

protected

def output_buffer=(val)
template.instance_variable_set(:@_out_buf, val)
end
end
OutputHelpers.register(SlimHandler)
OutputHelpers.register(:slim, SlimHandler)
end
end
end
12 changes: 2 additions & 10 deletions padrino-helpers/test/fixtures/markup_app/app.rb
@@ -1,22 +1,14 @@
require 'sinatra/base'
require 'haml'
require 'erubis'
require 'slim'
require 'padrino-core/application/rendering/extensions/erubis'
require 'padrino-core/application/rendering/extensions/haml'
require 'padrino-core/application/rendering/extensions/slim'
require 'padrino-core'

class MarkupDemo < Sinatra::Base
register Padrino::Helpers
register Padrino::Rendering

configure do
set :logging, false
set :padrino_logging, false
set :environment, :test
set :root, File.dirname(__FILE__)
set :erb, :engine_class => Padrino::Erubis::SafeBufferTemplate
set :haml, :escape_html => true
set :slim, :generator => Temple::Generators::RailsOutputBuffer, :buffer => "out_buf"
set :sessions, true
set :protect_from_csrf, true
end
Expand Down
4 changes: 2 additions & 2 deletions padrino-helpers/test/fixtures/markup_app/views/button_to.haml
@@ -1,5 +1,5 @@
- button_to 'Foo button', '/foo', :class => 'foo-form' do
- field_set_tag do
= button_to 'Foo button', '/foo', :class => 'foo-form' do
= field_set_tag do
= label_tag :username
= content_tag(:p, 'button_to test', :id => 'test-point')
= button_to 'Bar button', '/bar'
Expand Up @@ -3,10 +3,10 @@
%span Captured Line 2
= @content

- concat_in_p('Concat Line 3')
= concat_in_p('Concat Line 3')

- concat_if_block_is_template('haml') do
= concat_if_block_is_template('haml') do
%span This is haml
%span This is haml

- concat_ruby_not_template_block
= concat_ruby_not_template_block

0 comments on commit 8bb8124

Please sign in to comment.