Class: ActionView::StreamingTemplateRenderer
Do not use. This class is for internal use only.
| Relationships & Source Files | |
| Namespace Children | |
|
Classes:
| |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
self,
TemplateRenderer,
AbstractRenderer
|
|
|
Instance Chain:
self,
TemplateRenderer,
AbstractRenderer
|
|
| Inherits: |
ActionView::TemplateRenderer
|
| Defined in: | actionview/lib/action_view/renderer/streaming_template_renderer.rb |
Overview
TODO
-
Support streaming from child templates, partials and so on.
-
Rack::Cacheneeds to support streaming bodies
Constant Summary
AbstractRenderer - Inherited
Class Method Summary
AbstractRenderer - Inherited
Instance Attribute Summary
AbstractRenderer - Inherited
Instance Method Summary
-
#render_template(view, template, layout_name = nil, locals = {})
For streaming, instead of rendering a given a template, we return a
Bodyobject that responds to each. - #delayed_render(buffer, template, layout, view, locals) private
TemplateRenderer - Inherited
| #render, | |
| #determine_template | Determine the template to be rendered using the given options. |
| #find_layout | This is the method which actually finds the layout using details in the lookup context object. |
| #render_template | Renders the given template. |
| #render_with_layout, #resolve_layout | |
AbstractRenderer - Inherited
Constructor Details
This class inherits a constructor from ActionView::AbstractRenderer
Instance Method Details
#delayed_render(buffer, template, layout, view, locals) (private)
[ GitHub ]# File 'actionview/lib/action_view/renderer/streaming_template_renderer.rb', line 63
def delayed_render(buffer, template, layout, view, locals) # Wrap the given buffer in the StreamingBuffer and pass it to the # underlying template handler. Now, every time something is concatenated # to the buffer, it is not appended to an array, but streamed straight # to the client. output = ActionView::StreamingBuffer.new(buffer) yielder = lambda { |*name| view._layout_for(*name) } ActiveSupport::Notifications.instrument( "render_template.action_view", identifier: template.identifier, layout: layout && layout.virtual_path, locals: locals ) do outer_config = I18n.config fiber = Fiber.new do I18n.config = outer_config if layout layout.render(view, locals, output, &yielder) else # If you don't have a layout, just render the thing # and concatenate the final result. This is the same # as a layout with just <%= yield %> output.safe_concat view._layout_for end end # Set the view flow to support streaming. It will be aware # when to stop rendering the layout because it needs to search # something in the template and vice-versa. view.view_flow = StreamingFlow.new(view, fiber) # Yo! Start the fiber! fiber.resume # If the fiber is still alive, it means we need something # from the template, so start rendering it. If not, it means # the layout exited without requiring anything from the template. if fiber.alive? content = template.render(view, locals, &yielder) # Once rendering the template is done, sets its content in the :layout key. view.view_flow.set(:layout, content) # In case the layout continues yielding, we need to resume # the fiber until all yields are handled. fiber.resume while fiber.alive? end end end
#render_template(view, template, layout_name = nil, locals = {})
For streaming, instead of rendering a given a template, we return a StreamingTemplateRenderer::Body object that responds to each. This object is initialized with a block that knows how to render the template.
# File 'actionview/lib/action_view/renderer/streaming_template_renderer.rb', line 51
def render_template(view, template, layout_name = nil, locals = {}) # :nodoc: return [super.body] unless template.supports_streaming? locals ||= {} layout = find_layout(layout_name, locals.keys, [formats.first]) Body.new do |buffer| delayed_render(buffer, template, layout, view, locals) end end