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::Cache
needs 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
Body
object 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 56
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 44
def render_template(view, template, layout_name = nil, locals = {}) # :nodoc: return [super.body] unless layout_name && 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