Merge pull request #1005 from christopheraue/render_refactor

Refactored and optimized rendering
This commit is contained in:
Dylan Thacker-Smith
2018-04-19 16:44:57 -04:00
committed by GitHub
2 changed files with 37 additions and 33 deletions
+33 -29
View File
@@ -70,33 +70,27 @@ module Liquid
output = [] output = []
context.resource_limits.render_score += @nodelist.length context.resource_limits.render_score += @nodelist.length
@nodelist.each do |token| idx = 0
# Break out if we have any unhanded interrupts. while node = @nodelist[idx]
break if context.interrupt? case node
when String
begin check_resources(context, node)
output << node
when Variable
render_node_to_output(node, output, context)
when Block
render_node_to_output(node, output, context, node.blank?)
break if context.interrupt? # might have happened in a for-block
when Continue, Break
# If we get an Interrupt that means the block must stop processing. An # If we get an Interrupt that means the block must stop processing. An
# Interrupt is any command that stops block execution such as {% break %} # Interrupt is any command that stops block execution such as {% break %}
# or {% continue %} # or {% continue %}
if token.is_a?(Continue) || token.is_a?(Break) context.push_interrupt(node.interrupt)
context.push_interrupt(token.interrupt) break
break else # Other non-Block tags
end render_node_to_output(node, output, context)
node_output = render_node(token, context)
unless token.is_a?(Block) && token.blank?
output << node_output
end
rescue MemoryError => e
raise e
rescue UndefinedVariable, UndefinedDropMethod, UndefinedFilter => e
context.handle_error(e, token.line_number)
output << nil
rescue ::StandardError => e
line_number = token.is_a?(String) ? nil : token.line_number
output << context.handle_error(e, line_number)
end end
idx += 1
end end
output.join output.join
@@ -104,15 +98,25 @@ module Liquid
private private
def render_node(node, context) def render_node_to_output(node, output, context, skip_output = false)
node_output = node.is_a?(String) ? node : node.render(context) node_output = node.render(context)
node_output = node_output.is_a?(Array) ? node_output.join : node_output.to_s node_output = node_output.is_a?(Array) ? node_output.join : node_output.to_s
check_resources(context, node_output)
output << node_output unless skip_output
rescue MemoryError => e
raise e
rescue UndefinedVariable, UndefinedDropMethod, UndefinedFilter => e
context.handle_error(e, node.line_number)
output << nil
rescue ::StandardError => e
line_number = node.is_a?(String) ? nil : node.line_number
output << context.handle_error(e, line_number)
end
def check_resources(context, node_output)
context.resource_limits.render_length += node_output.length context.resource_limits.render_length += node_output.length
if context.resource_limits.reached? return unless context.resource_limits.reached?
raise MemoryError.new("Memory limits exceeded".freeze) raise MemoryError.new("Memory limits exceeded".freeze)
end
node_output
end end
def create_variable(token, parse_context) def create_variable(token, parse_context)
+4 -4
View File
@@ -1,13 +1,13 @@
module Liquid module Liquid
class BlockBody class BlockBody
def render_node_with_profiling(node, context) def render_node_with_profiling(node, output, context, skip_output = false)
Profiler.profile_node_render(node) do Profiler.profile_node_render(node) do
render_node_without_profiling(node, context) render_node_without_profiling(node, output, context, skip_output)
end end
end end
alias_method :render_node_without_profiling, :render_node alias_method :render_node_without_profiling, :render_node_to_output
alias_method :render_node, :render_node_with_profiling alias_method :render_node_to_output, :render_node_with_profiling
end end
class Include < Tag class Include < Tag