Permalink
Browse files

Rendering directly to _erbout when integrating with ActionView.

  • Loading branch information...
1 parent 834ab74 commit 55c07be7ff0d96f9e1e9017718bc8a4fd809131a @btakita btakita committed Jun 8, 2008
@@ -1,12 +1,16 @@
module ActionView #:nodoc:
module TemplateHandlers #:nodoc:
- class Erector
+ class Erector < TemplateHandler
+ def self.line_offset
+ 2
+ end
+
attr_reader :view
def initialize(view)
@view = view
end
- def render(template, local_assigns)
+ def compile(template)
render_path = view.first_render
paths = render_path.split('/')
dot_rb = /\.rb$/
@@ -17,12 +21,17 @@ def render(template, local_assigns)
else
require_dependency file_path
end
- widget_class = paths[0..-1].inject(Views) do |current_module, node|
- current_module.const_get(node.gsub(dot_rb, '').camelize)
+
+ dot_rb = /\.rb$/
+ widget_class_parts = paths.inject(['Views']) do |class_parts, node|
+ class_parts << node.gsub(dot_rb, '').camelize
+ class_parts
end
+ widget_class_name = widget_class_parts.join("::")
+ render_method = view.is_partial_template? ? 'render_partial' : 'render'
- rendered_widget = widget_class.new(@view, @view.assigns)
- rendered_widget.to_s(view.is_partial_template? ? :render_partial : :render)
+ erector_template = "<% #{widget_class_name}.new(self, assigns, StringIO.new(_erbout)).#{render_method} %>"
+ ::ERB.new(erector_template, nil, @view.erb_trim_mode).src
end
end
end
@@ -1,22 +1,17 @@
ActionController::Base.class_eval do
def render_widget(widget_class, assigns=@assigns)
- render :text => render_widget_to_string(widget_class, assigns)
- end
-
- def render_widget_to_string(widget_class, assigns = @assigns)
+ @__widget_class = widget_class
+ @__widget_assigns = assigns
add_variables_to_assigns
- @rendered_widget = widget_class.new(@template, assigns.merge(:params => params))
- @rendered_widget.to_s
+ render :inline => "<% @__widget_class.new(self, @__widget_assigns, StringIO.new(_erbout)).render %>"
end
def render_with_erector_widget(*options, &block)
if options.first.is_a?(Hash) && widget = options.first.delete(:widget)
- render_widget widget, *options, &block
+ render_widget widget, @assigns, &block
else
render_without_erector_widget *options, &block
end
end
alias_method_chain :render, :erector_widget
-
- attr_reader :rendered_widget
end
@@ -1,6 +1,11 @@
module Erector
Widget.class_eval do
include ActionController::UrlWriter
+ attr_reader :_erbout
+
+ after_initialize do
+ @_erbout = doc.string
+ end
# helpers returning raw text
[
View
@@ -43,6 +43,14 @@ def full_tags
]
end
+ def after_initialize(&blk)
+ after_initialize_parts << blk
+ end
+
+ def after_initialize_parts
+ @after_initialize_parts ||= []
+ end
+
end
attr_reader :helpers
@@ -58,6 +66,9 @@ def initialize(helpers=nil, assigns={}, io = StringIO.new(""), &block)
@parent = block ? eval("self", block.binding) : nil
@doc = Doc.new(io)
@block = block
+ self.class.after_initialize_parts.each do |part|
+ instance_eval(&part)
+ end
end
#-- methods for other classes to call, left public for ease of testing and documentation
@@ -12,7 +12,8 @@ def index_with_explicit_assigns
end
def index_with_render_colon_widget
- render :widget => TestWidget, :foobar => "foobar"
+ @foobar = "foobar"
+ render :widget => TestWidget
end
end
@@ -31,17 +32,11 @@ def render
@controller.send(:initialize_template_class, @response)
@controller.send(:assign_shortcuts, @request, @response)
class << @controller
- public :rendered_widget, :render
+ public :render
end
end
describe "#render_widget" do
- it "assigns to @rendered_widget" do
- @controller.rendered_widget.should be_nil
- @controller.render_widget TestWidget
- @controller.rendered_widget.should be_instance_of(TestWidget)
- end
-
it "instantiates a widget with implicit assigns" do
@controller.index_with_implicit_assigns
@response.body.should == "foobar"
@@ -54,24 +49,12 @@ class << @controller
end
describe "#render :widget" do
- it "assigns to @rendered_widget" do
- @controller.rendered_widget.should be_nil
- @controller.render :widget => TestWidget
- @controller.rendered_widget.should be_instance_of(TestWidget)
- end
-
it "instantiates a widget with implicit assigns" do
@controller.index_with_implicit_assigns
@response.body.should == "foobar"
end
describe "#render :widget" do
- it "assigns to @rendered_widget" do
- @controller.rendered_widget.should be_nil
- @controller.render :widget => TestWidget
- @controller.rendered_widget.should be_instance_of(TestWidget)
- end
-
it "instantiates a widget with explicit assigns" do
@controller.index_with_render_colon_widget
@response.body.should == "foobar"
@@ -14,7 +14,7 @@ class TemplateHandlerSpecController < ActionController::Base
@controller.send(:initialize_template_class, @response)
@controller.send(:assign_shortcuts, @request, @response)
class << @controller
- public :rendered_widget, :render
+ public :render
end
@controller.append_view_path("#{RAILS_ROOT}/app/views")
controller.instance_variable_set('@foo', "foo")
@@ -15,7 +15,7 @@ class RailsHelpersSpecController < ActionController::Base
@controller.send(:assign_shortcuts, @request, @response)
@controller.send(:initialize_current_url)
class << @controller
- public :rendered_widget, :render
+ public :render
attr_accessor :user # dummy instance variable for assigns testing
end
@@ -131,14 +131,22 @@ def render
pending("error_messages_for is broken")
widget_class = Class.new(Erector::Widget) do
def render
- error_messages_for 'user'
+ rawtext error_messages_for('user')
end
end
- errors = ActiveRecord::Errors.new(nil)
+
+ user_class = Class.new
+ stub(user_class).human_attribute_name {'User'}
+ user = user_class.new
+ stub(user).name {'bob'}
+ errors = ActiveRecord::Errors.new(user)
errors.add("name", "must be unpronounceable")
- @controller.user = OpenStruct.new({:name => 'bob', :errors => errors})
+ stub(user).errors {errors}
+
+ @controller.user = user
+
@controller.render :widget => widget_class
- @response.body.should == "<a href=\"#\" onclick=\"alert('hi'); return false;\">hi</a>"
+ @response.body.should == "<div class=\"errorExplanation\" id=\"errorExplanation\"><h2>1 error prohibited this user from being saved</h2><p>There were problems with the following fields:</p><ul><li>User must be unpronounceable</li></ul></div>"
end
end

0 comments on commit 55c07be

Please sign in to comment.